Java自学之反射——自学笔记

Object类中有一个getClass()方法,是用于获取当前对象所述的类信息,返回Class对象。这个方法在Class类中是典型的使用。
使用反射的起点总是java.lang.Class 实例。
什么是反射 反射机制指的是程序在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。至于为什么名字取名叫反射,我想的等我写完就知道为什么了。
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

Class类的使用 怎么理解Class类呢,在Java里,万物皆对象(在Java中只有两个东西不是对象,一个是静态成员,一个是基本数据类型,但是基本数据类型也有他的包装类来弥补它),一个类也可以是一个对象,既然是对象,那么必然这个对象就有类型。比如我们声明一个对象的引用变量的时候,这个引用变量的类型就是类类型,比如A a=new A(); ,这时候a的类型就是类类型。那么类作为对象的时候,class类就是它的类型,即类是java.lang.Class 实例对象。
一般一个类的对象怎么表示呢,我们用A a=new A(); 这样就表示出来了,那么这个A类本身也是一个Class类的一个对象,那么这个类怎么表示呢,这个类就不能new出来了,
因为他的构造方法是私有的private Class(){ },在类的外部是不能直接创建的,是由JVM创建的,那么我们怎么表示这个实例对象呢。三种方法:

  1. Class c1=A.class; 这种方法也是在告诉我们任何一个类都有一个隐含的静态成员变量class。
  2. 已知该类的对象通过getClass(),Class c2=a.getClass();
    官方对于c1,c2是这么说的,表示了A类的类类型(class type),万事万物皆对象,类也是对象,是class的实例对象,这个对象我们成为该类的类类型。这时候c1等于c2的,c1和c2都代表了A类的类类型,一个类只能有一个类类型。
  3. Class c3=null; c3=Class.forName(“类名全称”); c1c2c3
我们可以通过该类的类类型创建该类的对象,即通过c1或者c2或者c3创建A类的对象。如A a=(A)c1.newInstance(); newInstance(); 返回值类型是Object的,需要强制类型转换。前提是需要有无参的构造方法,因为他会去调用无参的构造方法。
动态加载 动态加载:在程序运行时才会加载class文件。静态加载:在程序编译期间去加载class文件。class.forName()是在运行期间加载的。在编译时刻加载的话需要把所有运行时可能用到的类都加载,如果没有,就会报错。但在实际中我们需要用到那个类就去加载哪个类,这就需要在运行时去加载需要用到的类,这就不会报错了。
反射可以通过类类型去获取类的方法的信息,成员的信息。
方法反射的基本操作 【Java自学之反射——自学笔记】两个步骤
  1. 获取某个方法:方法的名称和方法的参数列表才能唯一确定一个方法。
  2. 方法反射的操作:method.invoke(对象,参数列表);
package com.ann.test; import java.lang.reflect.Method; public class MethodDemo1 { public static void main(String[] args) { //要获取print(int,int)方法 1.要获取一个方法就是获取类的信息,获取累的信息首要获取类的类类型 A a1 = new A(); Class c = a1.getClass(); /*2.获取方法 名称和参数列表来决定 *getMthod获取的是public的方法 *getDelcaredMethod是获取自己声明的方法 */ try { //c.getMethod("print", new Class[]{int.class,int.class}); Method m=c.getMethod("print", int.class,int.class); //方法的反射操作 //a1.print(10,20); 方法的反射操作是用m对象来进行方法调用和a1.print调用的效果一样的 //方法如果没有返回值返回null,有返回值返回具体的返回值 Object o=m.invoke(a1, new Object[]{10,20}); System.out.println("--------"); Method m1 = c.getMethod("print", String.class,String.class); //用方法进行反射操作 //a1.print("hello","WORLD"); o = m1.invoke(a1,"hello","WORLD"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class A{ public void print(int a,int b) { System.out.println(a+b); } public void print(String a,String b) { System.out.println(a.toUpperCase()+","+b.toLowerCase()); } } **至于为什么叫反射,是因为反射的本质就是得到class对象后,反向获取class对象的对象的信息**

    推荐阅读