------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
反射
例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示。就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。
所有的类文件都有共同属性,所以可以向上抽取,把这些共性内容封装成一个类,这个类就叫Class(描述字节码文件的对象)。
Class类中就包含属性有field(字段)、method(方法)、construction(构造函数)。
字节码:
当源程序中用到类时,首先要从硬盘把这个类的那些二进制代码,一个类编译成class放在硬盘上以后,就是一些二进制代码,要把这些二进制代码加载到内存中里面来,再用这些字节码去复制出一个一个对象来。
三种加载字节码的方式:
类名.class
对象.getClass();
Class.forName("");
构造方法的反射
Constructor类代表某个类中的一个构造方法。
获取构造方法:
得到这个类的所有构造方法:
Constructor[] constructor = Class.forName(“java.lang.String”).getConstructors();
获取某一个构造方法:
Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc");
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Reflect {
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
String str1 = (String)constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str1.charAt(2));
}
}
运行结果:c
成员变量的反射
Field类代表某个类中一个成员变量
方法
Field getField(String s);//只能获取公有和父类中公有
Field getDeclaredField(String s);//获取该类中任意成员变量,包括私有
setAccessible(ture);
//如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。
set(Object obj, Object value);//将指定对象变量上此Field对象表示的字段设置为指定的新值。
Object get(Object obj);//返回指定对象上Field表示的字段的值。
<span style="font-size:12px;">import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Reflect {
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException {
// Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
// String str1 = (String)constructor1.newInstance(new StringBuffer("abc"));
// System.out.println(str1.charAt(2));
ReflectPoint pt = new ReflectPoint(3,5);
Field fieldY = pt.getClass().getField("y");
System.out.println(fieldY.get(pt));
}
}
class ReflectPoint{
private int x;
public int y;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
}</span>
Method类代表某个类中的一个成员方法
得到类中的某个方法:例: Method charAt =Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(str.charAt().invoke(str,1);
public class Reflect {
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException {
String str1 = "abc";
Method methodcharat = String.class.getMethod("charAt", int.class);
System.out.println(methodcharat.invoke(str1, 1));
}
}
代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class.
基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用;非基本类型的一维数组,即可以当做Object类型使用,又可以当做Object[]使用。
Arrays.asList()方法处理int[]和String[]时的差异。
Array工具类用于完成对数组的反射操作。
import java.lang.reflect.Array;
import java.util.Arrays;
public class ArrayReflect {
public static void main(String[] args) {
int [] a1 = new int[]{1,2,3};
int [] a2 = new int[4];
int[][] a3 = new int[2][3];
String [] a4 = new String[]{"a","b","c"};
System.out.println(a1.getClass().equals(a2.getClass()));//true
System.out.println(a1.getClass().equals(a3.getClass()));//false
System.out.println(a1.getClass().equals(a4.getClass()));//false
System.out.println(a1.getClass().getName());//[I
System.out.println(a4.getClass().getName());//[Ljava.lang.String;
System.out.println(a1.getClass().getSuperclass());//class java.lang.Object
System.out.println(a4.getClass().getSuperclass());//class java.lang.Object
Object obj1=a1;
Object obj2=a3;
Object obj3=a4;
// Object[] obj11=a1;//这样是不行的,因为a1中的元素是int类型,基本数据类型不是Object
Object[] obj13=a3;
Object[] obj14=a4;//这样可以,因为String数组中的元素属于Object
System.out.println(a1);//[I@4caaf64e
System.out.println(a4);//[Ljava.lang.String;@6c10a234
System.out.println(Arrays.asList(a1));//[I@4caaf64e
System.out.println(Arrays.asList(a4));//[a, b, c]
printObject(a1);
printObject(a4);
printObject("abc");
}
//打印任意数值
private static void printObject(Object obj) {
Class clazz=obj.getClass();
//如果传入的是数组,则遍历
if(clazz.isArray()){
int len =Array.getLength(obj);//Array工具类获取数组长度方法
for(int x=0;x<len;x++){
System.out.println(Array.get(obj, x));//Array工具获取数组元素
}
}
else
System.out.println(obj);
}
}
反射的作用:实现框架功能