1. 代码运行示例:
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class ReflectionFirst {
public static void main(String[] args) throws Exception {
// 1 创建 class
Class clazz = Class.forName("java.util.ArrayList");
// 或使用 Class clazz = ArrayList.class;
// 2 可以使用class 获得该类的 method
Method methods[] = clazz.getMethods();
System.out.println(clazz.getPackage());
System.out.println(clazz.getName());
System.out.println("反射得到该类的所有方法:");
for (Method method : methods) {
System.out.println(method);
}
// 2.2 动态调用方法
ArrayList obj = (ArrayList) clazz.newInstance();
Method m = clazz.getMethod("add", Object.class);
m.invoke(obj, new Object[] { 1 });
System.out.println("invoke:" + obj);
// 3 可以使用class 获得该类实现的接口
System.out.println("反射得到该类实现的接口:");
Class interfaces[] = clazz.getInterfaces();
for (Class inter : interfaces) {
System.out.println(inter.getName());
}
// 4 可以使用class 获得该类实现的接口
System.out.println("使用测试类测试Field:");
TestPojo test = new TestPojo("f1", "f2", 3);
Class testClazz = test.getClass();
for (Method method : testClazz.getMethods()) {
System.out.println(method);
}
// 5 可以根据获得的 Constructor 动态的创建对象
Constructor[] cons = clazz.getConstructors();
System.out.println("length:" + cons.length);
for (Constructor con : cons) {
System.out.println("-------------" + con);
}
// 6 可以根据 Constructor 动态创建对象 创建对象
Class[] types = new Class[] { String.class, String.class, int.class };
Object[] arguments = new Object[] { "f11", "f22", 33 };
Constructor strCon = testClazz.getConstructor(types);
TestPojo testxx = (TestPojo) strCon.newInstance(arguments);
System.out.println(testxx);
// 7 proxy
}
}
2.测试POJO类 :本类用于测试字段和使用Constructor 动态创建对象
public class TestPojo {
private String field1;
private String field2;
private int field3;
private String field4;
public TestPojo(String field1, String field2, int field3) {
this.field1 = field1;
this.field2 = field2;
this.field3 = field3;
}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
public int getField3() {
return field3;
}
public void setField3(int field3) {
this.field3 = field3;
}
public String getField4() {
return field4;
}
public void setField4(String field4) {
this.field4 = field4;
}
}
3. java 反射机制相关概念和原理介绍:此部分内容来自:http://coffeelover.iteye.com/blog/611181
运行一下代码, 看一下该文的介绍,可以对反射扫扫盲了
要点
- Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象(根据安全性限制),无需提前硬编码目标类。这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。
-
Java反射机制主要提供了以下功能:
1) 在运行时判断任意一个对象所属的类;
2) 在运行时构造任意一个类的对象;
3) 在运行时判断任意一个类所具有的成员变量和方法;
4) 在运行时调用任意一个对象的方法;
5) 生成动态代理。--关于这个地方还没有测试,标记一下
-
反射的缺点:
1) 性能问题:当用于字段和方法接入时反射要远慢于直接代码。
2) 使用反射会模糊程序内部实际要发生的事情。程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术会带来维护问题。
-
在JDK类库中, 主要由以下类来实现Java反射机制, 这些类都位于 java.lang.reflect 包中。
Class类:代表一个类。
Field类:代表类的属性。
Method类:代表类的方法。
Constructor 类:代表类的构造方法。
Array类:提供了动态创建数组,以及访问数组元素的静态方法。
Proxy类和 InvocationHandler 接口:提供了生成动态代理类及其实例的方法。
相关问题
1. Q: 在Java 运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?
A: 均能。
2. Q: Java 反射机制的应用?
A: 运行时复制对象;运行时改变属性值;远程方法调用;代理模式中的代理类(静态代理类、动态代理类);对象关系映射ORM(如 Hibernate)。
3. Q: 以下哪些说法正确?(多选)
A.动态代理类与静态代理类一样,必须由开发人员编写源代码,并编译成.class文件
B.代理类与被代理类具有同样的接口
C.java.lang.Exception类实现了 java.io.Serializable接口,因此Exception对象可以被序列化后在网络上传输
D.java.lang.reflect包中的 Proxy 类提供了创建动态代理类的方法
Answer: BCD。
4. Q: 以下哪些属于动态代理类的特点?(多选)
A.动态代理类是public、final和非抽象类型的
B.动态代理类继承了java.lang.reflect.Proxy类
C.动态代理类实现了 getProxyClass()或 newProxyInstance()方法中参数interfaces指定的所有接口
D.动态代理类可以继承用户自定义的任意类
E.动态代理类都具有一个 public 类型的构造方法,该构造方法有一个InvocationHandler 类型的参数
Answer: ABCE。