返回顶部

反射

 Java的反射(reflection)机制是指在程序的运行状态中

可以构造任意一个类的对象

可以了解任意一个对象所属的类

可以了解任意一个类的成员变量和方法

可以调用任意一个对象的属性和方法

这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

 

Java反射描述的是,在运行状态中:

1、对于任意一个类,都能够知道这个类的所有属性和方法

2、对于任意一个类,都能够调用它的任意一个属性和方法

之所以强调属性、方法,是因为属性、方法是开发者对于一个类最关注的两个部分。实际上通过反射,不仅仅可以获知类的属性、方法,还可以获知类的父类、接口、包等信息

至于反射的原理,不难,Java类加载机制一文中讲到了,一个类在加载的时候,会在内存中生成一个代表这个.class文件的java.lang.Class对象,.classs文件里面就包含了描述这个类的信息的一切内容。至于.class文件,是由Java编译器(注意是Java编译器,指的不仅仅是Javac)编译而来的,是编译原理的领域;.class文件结构,网上很多讲解了,比如类文件结构,这里就不讲了。

一、获取class对象的方式

1. Class.forName("全类名")
  将字节码文件加载进内存,返回Class对象
  这是一个静态的方法static   
多用于配置文件,将类名定义在配置文件中。读取文件,加载类
2. 类名.class:通过类名的属性class获取 多用于参数的传递

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

出现这个问题可能是包名或者类名写错了。

Class cls1 = Class.forName("cn.ww.Person");
Class cls2=Person.class;
Person ps=new Person();
Class cls3 = ps.getClass();
System.out.println(cls2==cls3);
System.out.println(cls1==cls3);
System.out.println(cls1==cls2);
//返回值全都为true

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

 二、class对象功能

1、获取功能

1)获取成员变量们

① Field[] getFields() :获取所有public修饰的成员变量
②Field getField(String name) 获取指定名称的 public修饰的成员变量

//获取成员变量以后可以进行操作,已知有一个Person对象
//首先获取Person的Class对象
Class personClass =Person.class;
Field fields = personClass.getField("a") //获取成员变量中 public String a 中 的值
Person p = new Person();
Object value=fields.get(p);

//结果就会打印a的值
//set 和 get 两个方法

③ Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
④Field getDeclaredField(String name)

Class personClass =Person.class;//获取Person的class对象
Field d = personClass.getDeclaredField("d"); //忽略访问权限修饰符的安全检查 d.setAccessible(true);//暴力反射 Object value =d.get(p);

 

2)获取构造方法们

方法名和类名相同,本质就是来创建对象的

① Constructor<?>[] getConstructors()
② Constructor<T> getConstructor(类<?>... parameterTypes)

③ Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
④ Constructor<?>[] getDeclaredConstructors()

Constructor constructor =personClass.getConstructor(String.class , int.class);//返回了一个构造器

Object person = constructor.newInstance("你好",18);//创建对象

Object person = constructor.newInstance();//空参
//如果使用空参构造,可以直接使用class对象里面的方法
Class personClass = Person.class;
personClass。newInstance();

 

 3)获取成员方法们

  ①Method[] getMethods()       只能获取public的
  ②Method getMethod(String name, 类<?>... parameterTypes)

  ③Method[] getDeclaredMethods()      不考虑修饰符
  ④Method getDeclaredMethod(String name, 类<?>... parameterTypes)

   

     Class personClass =Person.class;
        Method eat2 = personClass.getMethod("eat2",String.class);
        Person person = new Person();
        eat2.invoke(person,"米饭");

 

posted @ 2020-06-12 22:56  可乐葱花  阅读(121)  评论(0编辑  收藏  举报