反射机制是在运行状态中,对于任意一类,都能够知道这个类中的所有属性和方法;对于任意一个对象,能够调用它的任意方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射就是把类中的各种成分映射成为相应的java类。
1、Class是Java程序中各个Java类的总称;它是反射的基石,通过Class类来使用反射。
2、Class和class的区别
1)class:Java中的类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则由此类的实例对象确定,不同的实例对象有不同的属性值。
2)Class:指的是Java程序中的各个Java类是属于同一类事物,都是Java程序的类,这些类称为Class。例如人对应的是Person类,Java类对应的就是Class。
获得Class对象
加载Class的方法
类名.class
实例.getclass
4、九个预定义的Class:
1)包括八种基本类型(byte、short、int、long、float、double、char、boolean)的字节码对象和一种返回值为void类型的void.class。
2)Integer.TYPE是Integer类的一个常量,它代表此包装类型包装的基本类型的字节码,所以和int.class是相等的。
基本数据类型的字节码都可以用与之对应的包装类中的TYPE常量表示
数组类型的Class实例对象,可以用Class.isArray()方法判断是否为数组类型的。
一、Constructor类
1、概述:Constructor代表某个类的构造方法
2、获取构造方法:
1)如何得到摸个类的所有构造方法:如得到String类的所有构造方法
Constructor[] cons = Class.forName(“java.lang.String”).getConstructors();
2)获取某一个构造方法:
Constructor con =String.class.getConstructor(StringBuffer.class);①
3、创建实例对象:
1)通常方式:String str = new String(new StringBuffer (”abc”));
2)反射方式:String str = (String)con.newInstance(new StringBuffer(“abc”));②
调用获得的方法时要用到上面相同类型的实例对象,即两个StringBuffer()要对应相等。
NewInstance():构造出一个实例对象,每调用一次就构造一个对象。
注意:上面的两个地方①②都要用到StringBuffer,这必须是一致的。
第①个是指定要带StringBuffer参数类型的构造方法,即所需使用的是含StringBuffer类型的构造方法。
第②个是用这个构造方法创建对象,要传入的参数类型是StringBuffer。
4、Class.newInstance():创建一个对象,不带参数的构造方法。
public class RefectDome {
public static void main(String[] args) throws Exception {
Class studentClazz = Class.forName("com.refect.Student");
Constructor[] conArr = studentClazz.getDeclaredConstructors();
for (Constructor constructor : conArr) {
System.out.println(constructor);
}
System.out.println("-------------------------------------");
Constructor con = studentClazz.getConstructor(String.class, int.class,
int.class, int.class);
System.out.println(con);
Object o = con.newInstance("张三", 18, 79, 89);
System.out.println(o);
Student stu= (Student) studentClazz.newInstance();
System.out.println(stu);
}
}
二、Field类
1、概述:Field类代表成员变量(字段)的反射。
2、获取成员变量:
如上例子所示:
1)获取公有的成员变量:
getField(String name)和get(变量)
2)获取私有的成员变量:暴力反射
getDeclared(String name)
setAccessible(boolean b),将b设为true即可
get(变量)
public class FieldDome {
public static void main(String[] args) throws Exception{
Class clazz = Class.forName("com.refect.Student");
Constructor<Student> con = clazz.getDeclaredConstructor(String.class,
int.class, int.class, int.class);
Object obj=con.newInstance("张三",90,100,100);
// Properties
Field name = clazz.getDeclaredField("age");
name.setAccessible(true);
name.set(obj, 13);
System.out.println(obj);
}
三、Method类
1、概述:Method类代表某个类中的一个成员方法。
调用某个对象身上的方法,要先得到方法,再针对某个对象调用。
如人关门:
调用者:是门调用管的动作,对象是门,因为门知道如何执行关的动作,通过门轴之类的细节实现。
指挥者:是人在指挥门做关的动作,只是给门发出了关的信号,让门执行。
总结:变量使用方法,是方法本身知道如何实现执行的过程,也就是“方法对象”调用方法,才执行了方法的每个细节的。
3、获取某个类中的某个方法:(如String str = ”abc”)
1)通常方式:str.charAt(1)
2)反射方式:
Method charAtMethod =
Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
charAtMethod.invoke(str,1);
说明:如果传递给Method对象的invoke()方法的第一个参数为null,说明Method对象对应的是一个静态方法
public class RefectDome {
public static void main(String[] args) throws Exception {
Class studentClazz = Class.forName("com.refect.Student");
Constructor[] conArr = studentClazz.getDeclaredConstructors();
for (Constructor constructor : conArr) {
System.out.println(constructor);
}
System.out.println("-------------------------------------");
Constructor con = studentClazz.getConstructor(String.class, int.class,
int.class, int.class);
System.out.println(con);
Object o = con.newInstance("张三", 18, 79, 89);
System.out.println(o);
Student stu= (Student) studentClazz.newInstance();
System.out.println(stu);
}
}