如下文章字数大约1100字以及若干代码块,阅读时间需要20分钟左右。
相关技术内容会持续更新,大家可随时交流,欢迎关注本头条号。
Java反射机制是Java语言中一种很重要的机制,而且在很多框架中都有用到这种机制。在我们的程序结构中能动态获取类的信息以及动态调用对象的方法的功能来自于Java的反射机制(Reflection)。
在JDK中,提供了以下类来实现Java反射机制,这些类都位于java.lang.reflect包下:
Class类:代表一个类(注意:Class类位于java.lang包下);
Field类:代表类的成员变量;
Method类:代表类的方法;
Constructor类:代表类的构造方法;
Array类:提供了动态创建数组,以及访问数组的元素的静态方法。
通过API提供的这些类里的方法,我们可以动态获取想要的类的内部信息。
另外一点重要的是:
Class类中存在以下几个重要的方法:
1.getName()
一个Class对象描述了一个特定类的特定属性,而这个方法就是返回String形式的该类的简要描述。由于历史原因,对数组的Class对象
调用该方***产生奇怪的结果。
2.newInstance()
该方法可以根据某个Class对象产生其对应类的实例。需要强调的是,它调用的是此类的默认构造方法。例如:
MyObject x = new MyObject();
MyObject y = x.getClass().newInstance();
3.getClassLoader()
返回该Class对象对应的类的类加载器。
4.getComponentType()
该方法针对数组对象的Class对象,可以得到该数组的组成元素所对应对象的Class对象。例如:
int[] ints = new int[]{1,2,3};
Class class1 = ints.getClass();
Class class2 = class1.getComponentType();
而这里得到的class2对象所对应的就应该是int这个基本类型的Class对象。
5.getSuperClass()
返回某子类所对应的直接父类所对应的Class对象。
6.isArray()
判定此Class对象所对应的是否是一个数组对象。
知道了基本概念后,具体的代码内容:
假设测试类为 TestReflect,对应的路径为
singTest.invoke.TestReflect。
【1】通过一个对象获得完整的包名和类名
TestReflect testReflect = new TestReflect();
System.out.println("===="+ testReflect.getClass().getName());
System.out.println("===="+ testReflect.getClass().getName());
输出内容分别为:
singTest.invoke.TestReflect
class singTest.invoke.TestReflect
【2】 实例化Class类对象
Class<?> class1 = null;
Class<?> class2 = null;
Class<?> class3 = null;
class1 = Class.forName("singTest.invoke.TestReflect");
class2 = new TestReflect().getClass();
class3 = TestReflect.class;
System.out.println("===类名称 1===" + class1);
System.out.println("===类名称 2===" + class2);
System.out.println("===类名称 3===" + class3);
上述三种都是实例化对应的类,输出结果均为:class
singTest.invoke.TestReflect。
【3】获取某个类的全部属性
Class<?> clazz = Class.forName("singTest.invoke.TestReflect");
//取得本类中全部属性
//TestReflect 类中属性就是 serialVersionUID 与 test1
Field[] field = clazz.getDeclaredFields();
for(int i=0;i<field.length;i++){
//权限修饰符
int mo = field[i].getModifiers();
System.out.println("==mo=="+mo);
String priv = Modifier.toString(mo);
System.out.println("==priv=="+priv);
//属性类型
Class<?> type = field[i].getType();
System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");
}
会输出对应类下所有变量属性,具体可自己操作实验。
【4】通过反射机制调用某个类的方法
Class<?> clazz = Class.forName("singTest.invoke.TestReflect");
//调用 TestReflect 类中的 reflect1 方法
Method method = clazz.getMethod("reflect1");
//调用reflect1 方法
method.invoke(clazz.newInstance());
//输出:Java 反射机制 - 调用某个类的方法1
//调用reflect2方法
method = clazz.getMethod("reflect2",int.class,String.class);
method.invoke(clazz.newInstance(),20,"Tom");
//输出:Java 反射机制-调用某个类的方法2
以上为根据反射机制写的一些简单例子。最近工作较忙,总结有限。如果想继续深入,可以自己继续研究或者私信我。
后面看时间有可能发布一个关于反射相关的工具类。
下篇预告:讲解一下Linux中不同主机间的免密登录方法。
已上内容,纯属一家之言,因本人能力一般,见识有限,如有问题,请不吝指正,感谢。