黑马程序员-反射

来源:互联网 发布:学历网络教育报考 编辑:程序博客网 时间:2024/05/23 13:58

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

反射就是把Java类中的各种成分映射成相应的java类。

1.Constructor类
得到某个类所有的构造方法:
 Constructor[] constructors = Class.forName("java.lang.String").getConstructors();

得到某一个构造方法:
 Constructor constructor = Class.forName("java.lang.String").getConstuctor(StringBuffer.class);

创建实例对象:
 通常方式:String str = new String(new StringBuffer("abc"));
 反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));

public class ReflectDemo {public static void main(String[] args) throws Exception{Class s1 = String.class;System.out.println(s1);//通过字节码文件获取对象的构造方法,构造方法可能不止一个所以用数组存储Constructor[] constructors = String.class.getConstructors();for(Constructor constructor:constructors){//迭代出获取的构造方法System.out.println(constructor);}//获取单个构造方法,传入参数列表类型字节码Constructor constructor =String.class.getConstructor(StringBuffer.class);System.out.println("..."+constructor);//通过获取的构造方法创建对象String s2 = (String)constructor.newInstance(new StringBuffer("lisi"));System.out.println(s2);}}

2.Field类
Filed类代表某个类中的一个成员变量
得到某个类的成员变量并打印
ReflectPoint point = new ReflectPoint(1,7);
Field x = point.getClass().getField("x");
System.out.println(x.get(point));

如果成员变量是私有的可以用getDeclaredField()和setAccessible(true);
Field y = point.getClass().getDeclaredField("y");
y.setAccessible(true);
System.out.println(y.get(point));

首先,我们需要一个被反射的类,里面提供了set(),get()方法

class PersonDemo {//不同修饰符的成员字段public String name = "lisi";private int age = 17;public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}PersonDemo(){}public String getName(){return name;}public int getAge(){return age;}} 
然后我们要在另一个类中通过字节码文件对其进行访问

import java.lang.reflect.Constructor;import java.lang.reflect.Field;public class ReflectDemo {public static void main(String[] args) throws Exception{//实例化要反射的对象,加载其字节码文件PersonDemo p = new PersonDemo();System.out.println(p);//通过字节码,使用getField()方法反射得到的字段Field fieldName = p.getClass().getField("name");//打印获取的字段System.out.println(fieldName.get(p));//通过对象提供的set方法为字段重新赋值fieldName.set(p,"zhangsan");System.out.println(fieldName.get(p));//暴力反射,可以获取所有的字段,注意这里只是获取了字段但还没有操作权限Field fieldAge = p.getClass().getDeclaredField("age");//取消JAVA程序的访问检查fieldAge.setAccessible(true);System.out.println(fieldAge.get(p));}}

3.Method类

Method类代表某个类中的方法
得到类中的某一个方法:
 Method charAt = Class.forName("java.lang.String").getMethod("charAt",int.class);

调用方法:
 String str = "abc";
 通常方法:System.out.println(str.charAt(1));
 反射方法:System.out.println(charAt.invoke(str,1));运行结果b
 如果invoke(null,1) 代表调用的是一个静态的方法 

import java.lang.reflect.Method;public class ReflectMethod {public static void main(String[] args) throws Exception {PersonDemo p = new PersonDemo();//同种方法有不同的重载形式,所以使用数组Method[] ms = p.getClass().getMethods();for(Method m:ms){//循环打印获取的方法System.out.println("获得的方法:"+m);}//获取无参数的方法Method m1 = p.getClass().getMethod("getName");System.out.println("m1= ...."+m1+"...");//获取有参数的构造方法,传入参数类型字节码Method m2 = p.getClass().getMethod("setName",String.class);System.out.println("m2= ---"+m2+"---");//传入对象,传入参数列表类型System.out.println("方法实现:"+m1.invoke(p,null));}}

4 数组的反射:
具有相同维数和元素类型的数组属于同一个类型,既具有相同的Class实例对象。
代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用,非基本类型的一维数组,
既可以当做Object类型使用,又可以当做Object[]类型使用。

import java.lang.reflect.Array;public class ReflectArray {public static void main(String[] args) throws Exception{//一维数组int[] arr1 = new int[1];int[] arr2 = new int[3];//比较一维数组的字节码对象System.out.println(arr1.getClass().equals(arr2.getClass()));int[] arr3[] = new int[1][3]; //比较二维数组的字节码对象System.out.println(arr1.getClass().equals(arr3.getClass()));//数组类型int[]也是Object类型Object arr4[] = arr3;System.out.println(arr3.getClass());System.out.println(arr4.getClass());//通过反射获取数组类型的字节码文件Class cls = Class.forName("java.lang.String");//通过得到字节码类型创建一个长度为20的数组Object objArr = Array.newInstance(cls, 20);//为数组赋值Array.set( objArr, 1, "my name is liyeyeu");///通过字节码文件和角标获取数组的元素System.out.println(Array.get(objArr, 1));//数组长度System.out.println(Array.getLength(objArr));}}

0 0
原创粉丝点击