反射

反射

参考黑马程序员

框架设计的灵魂

框架:半成品软件。可以在框架的基础上进行软件开发,简化编码

概念:将类的各个组成部分封装为其他对象,这就是反射机制

好处:

  1. 可以在程序运行过程中,操作这些对象。

  2. 可以解耦,提高程序的可扩展性。

获取Class对象的方式:

  1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象

    • 多用于配置文件,将类名定义在配置文件中。读取文件,加载类

  2. 类名.class:通过类名的属性class获取

    • 多用于参数的传递

  3. 对象.getClass():getClass()方法在Object类中定义着。

    • 多用于对象的获取字节码的方式

    结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

代码

Person类

package cn.itcast.domain;

public class Person {
   private String name;
   private int age;

   public Person() {
  }

   public Person(String name, int age) {
       this.name = name;
       this.age = age;
  }

   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public int getAge() {
       return age;
  }

   public void setAge(int age) {
       this.age = age;
  }

   @Override
   public String toString() {
       return "Person{" +
               "name='" + name + '\'' +
               ", age=" + age +
               '}';
  }
}

ReflectDemo类

package cn.itcast.reflect;

import cn.itcast.domain.Person;

public class ReflectDemo1 {

   /*获取Class对象的方式:
           1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
           2. 类名.class:通过类名的属性class获取
           3. 对象.getClass():getClass()方法在Object类中定义着。*/

   public static void main(String[] args) throws Exception {

       //1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
       Class cls1 = Class.forName("cn.itcast.domain.Person");
       System.out.println(cls1);
       //2. 类名.class:通过类名的属性class获取
       Class cls2 = Person.class;
       System.out.println(cls2);
       //3. 对象.getClass():getClass()方法在Object类中定义着。
       Person person = new Person();
       Class cls3 = person.getClass();
       System.out.println(cls3);

       //== 比较三个对象
       System.out.println(cls1 == cls2);
       System.out.println(cls1 == cls3);
  }
}


Class对象功能:

获取功能:

  1. 获取成员变量们

Field[] getFields():获取所有public修饰的成员变量

Field getField(String name):获取指定名称的 public修饰的成员变量

 

Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符

Field getDeclaredField(String name)

  1. 获取构造方法们

Constructor<?>[] getConstructors()

Constructor<T> getConstructor(类<?>... parameterTypes)

 

Constructor<?>[] getDeclaredConstructors()

Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)

  1. 获取成员方法们

Method[] getMethods()

Method getMethod(String name, 类<?>... parameterTypes)

 

`Method[] getDeclaredMethods()

Method getDeclaredMethod(String name, 类<?>... parameterTypes)

  1. 获取类名

String getName()



Field:成员变量

操作:

  1. 设置值

void set(Object obj, Object value)

  1. 获取值

get(Object obj)

  1. 忽略访问权限修饰符的安全检查

setAccessible(true):暴力反射

代码

Person类

package cn.itcast.domain;

public class Person {
   private String name;
   private int age;

   public String a;
   protected String b;
   String c;
   private String d;

   public Person() {
  }

   public Person(String name, int age) {
       this.name = name;
       this.age = age;
  }

   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public int getAge() {
       return age;
  }

   public void setAge(int age) {
       this.age = age;
  }

   @Override
   public String toString() {
       return "Person{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", a='" + a + '\'' +
               ", b='" + b + '\'' +
               ", c='" + c + '\'' +
               ", d='" + d + '\'' +
               '}';
  }
}

ReflectDemo2

package cn.itcast.reflect;

import cn.itcast.domain.Person;

import java.lang.reflect.Field;

public class ReflectDemo2 {
   public static void main(String[] args) throws Exception {

       //0.获取Person的Class对象
       Class personClass = Person.class;
       /*
       1. 获取成员变量们
           Field[] getFields()
           Field getField(String name)

           Field[] getDeclaredFields()
           Field getDeclaredField(String name)
        */
       //1.Field[] getFields()获取所有public修饰的成员变量
       Field[] fields = personClass.getFields();
       for (Field field: fields) {
           System.out.println(field);
      }

       System.out.println("--------------");

       //2.Field getField(String name)
       Field a = personClass.getField("a");
       //获取成员变量a的值
       Person p = new Person();
       Object value = a.get(p);
       System.out.println(value);
       //设置a的值
       a.set(p,"张三");
       System.out.println(p);

       System.out.println("-----------------");

       //3.Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
       Field[] declaredFields = personClass.getDeclaredFields();
       for (Field declaredField: declaredFields) {
           System.out.println(declaredField);
      }
       //4.Field getDeclaredField(String name)
       Field d = personClass.getDeclaredField("d");
       //忽略访问权限修饰符的安全检查
       d.setAccessible(true);//暴力反射
       Object value2 = d.get(p);
       System.out.println(value2);
  }
}


Constructor:构造方法

创建对象:T newInstance(Object.. initargs)

如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

setAccessible(true):暴力反射

代码

person类(同上面Person类,不再重复)

ReflectDemo3类

package cn.itcast.reflect;

import cn.itcast.domain.Person;

import java.lang.reflect.Constructor;

public class ReflectDemo3 {
   public static void main(String[] args) throws Exception {

       //0.获取Person的Class对象
       Class personClass = Person.class;
       /*
       2. 获取构造方法们
           Constructor<?>[] getConstructors()
           Constructor<T> getConstructor(类<?>... parameterTypes)

           Constructor<?>[] getDeclaredConstructors()
           Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
        */

       //Constructor<T> getConstructor(类<?>... parameterTypes)
       Constructor constructor = personClass.getConstructor(String.class, int.class);
       System.out.println(constructor);
       //创建对象
       Object person = constructor.newInstance("张三", 23);
       System.out.println(person);

       System.out.println("-----------------------");

       Constructor constructor1 = personClass.getConstructor();
       System.out.println(constructor1);
       //创建对象
       Object person1 = constructor1.newInstance();
       System.out.println(person1);
​     //无参简化
       Object o = personClass.newInstance();
       System.out.println(o);
  }
}


Method:方法对象

执行方法:Object invoke(Object obj, Object... args)

setAccessible(true):暴力反射

获取方法名称:String getName():获取方法名

代码

Person类

package cn.itcast.domain;

public class Person {
   private String name;
   private int age;

   public String a;
   protected String b;
   String c;
   private String d;

   public Person() {
  }

   public Person(String name, int age) {
       this.name = name;
       this.age = age;
  }

   public String getName() {
       return name;
  }

   public void setName(String name) {
       this.name = name;
  }

   public int getAge() {
       return age;
  }

   public void setAge(int age) {
       this.age = age;
  }

   @Override
   public String toString() {
       return "Person{" +
               "name='" + name + '\'' +
               ", age=" + age +
               ", a='" + a + '\'' +
               ", b='" + b + '\'' +
               ", c='" + c + '\'' +
               ", d='" + d + '\'' +
               '}';
  }


   public void eat() {
       System.out.println("eat...");
  }

   public void eat(String food) {
       System.out.println("eat..." + food);
  }
}

ReflectDemo4类

package cn.itcast.reflect;

import cn.itcast.domain.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ReflectDemo4 {
   public static void main(String[] args) throws Exception {

       //0.获取Person的Class对象
       Class personClass = Person.class;
       /*
       3. 获取成员方法们
           Method[] getMethods()
           Method getMethod(String name, 类<?>... parameterTypes)

           Method[] getDeclaredMethods()
           Method getDeclaredMethod(String name, 类<?>... parameterTypes)
        */

       //获取指定名称的方法
       Method eat_method = personClass.getMethod("eat");
       Person p = new Person();
       //执行方法
       eat_method.invoke(p);

       Method eat_method2 = personClass.getMethod("eat", String.class);
       //执行方法
       eat_method2.invoke(p,"饭");

       System.out.println("-------------------");

       //获取所有public修饰的方法
       Method[] methods = personClass.getMethods();
       for (Method method: methods){
           System.out.println(method);
           String name = method.getName();
           System.out.println(name);
      }

       //获取类名
       String className = personClass.getName();
       System.out.println(className);//cn.itcast.domain.Person
  }
}

 

posted @ 2021-04-06 11:15  i爱在西元前  阅读(61)  评论(0)    收藏  举报