反射是java中最牛皮的一个技术,利用反射技术可以获取任意一个类一个类的框架,所有方法以及所有属性。
1,简单认识:
/*我们先尝试getclass来获取一个字符串所属的类*/ String name = "詹姆斯"; class c1 = name.getClass(); System.out.println(c1.getName()); //打印结果就是“java.lang.String”
2,获取类的成员:
实例类:
public class test{ private int age; private String name; private char sex; public int Age(int age){ return age; } public void Name(String name){ System.out.println(name); } private void Sex(char sex){ System.out.println(sex); } public void clazz(){ } }
-
获取类的指定构造方法并调用:
public static void main(String[] args){ /*加载class对象*/ class clazz = Class.forName("packagename.test"); System.out.println("获取所有的公有构造方法"); Constructor[] array = clazz.getConstructors(); for(Constructor c : array){ System.out.println(c); } System.out.println("获取所有的构造方法"); array = clazz.getDeclaredConstructor(); for(Constructor b : array){ Syetem.out.println(b); } System.out.println("获取公有的无参的构造方法"); Constructor con = clazz.getConstructor(null); /*这里需要的是一个参数类型,写null就是返回无参构造方法的类对象,不写也可以,写int就是指定返回参数为int型的构造方法的类对象*/ /*调用构造方法*/ Object obj = con.newInstance(); System.out,println("获取私有的构造方法并调用"); /*反射指定类型的构造方法,这里为int型,在实例类里就是Age方法*/ con = clazz.getDeclaredConstructor(int.class); System.out.println(con); con.setAccessible(true);/*暴力访问,忽略访问修饰符*/ obj = con.newInstance(18); }
3,反射原理:
类加载
-
编译:.java文件编译后生成.class字节码文件
-
加载:类加载器负责根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例
-
连接:细分三步
-
验证:格式(class文件规范) 语义(final类是否有子类) 操作
-
准备:静态变量赋初值和内存空间,final修饰的内存空间直接赋原值,此处不是用户指定的初值。
-
解析:符号引用转化为直接引用,分配地址
-
初始化:有父类先初始化父类,然后初始化自己;将static修饰代码执行一遍,如果是静态变量,则用用户指定值覆盖原有初值;如果是代码块,则执行一遍操作。
Java的反射是利用上面第二步加载到jvm中的.class文件来进行操作的。.class文件中包含java类的所有信息,当你不知道某个类具体信息时,可以使用反射获取class,然后进行各种操作。
Java反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。
总结:反射就是把java类中的各种成分映射成一个个的Java对象,并且可以进行操作。