1反射机制?
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
FAQ:反射有什么缺陷?会存在一定的"性能"问题.
1、性能问题,使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用
2、安全限制。
使用反射通常需要程序的运行没有安全方面的限制。如果一个程序对安全性提出要求,则最好不要使用反射。
3、程序健壮性。
反射允许代码执行一些通常不被允许的操作,所以使用反射有可能会导致意想不到的后果。反射代码破坏了Java程序结构的抽象性,所以当程序运行的平台发生变化的时候,由于抽象的逻辑结构不能被识别,代码产生的效果与之前会产生差异。
2反射核心API及应用加强
反射应用的入口为"字节码对象",任意的一个类在同一个JVM内部,字节码对象是唯一的,此字节码对象会在第一次类加载时创建,用于存储类的结构信息.
基于字节码对象,我们可以获取如下对象:
1)Constructor (构造方法对象类型,基于此对象构建类的实例对象)
2)Field (属性对象类型)
3)Method (方法对象类型)
4)Annotation(注解对象类型)
5)…
案例1:利用反射获取对象属性、构造函数和方法
class Reply{
private Long id;
private String title;
private Date ctreatTime;
private Reply() {
}
private Reply(Long id)
{
this.id=id;
}
}`
//程序入口,测试方法
public class ReflectTest01 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class<?> cls = Class.forName("reflect.Reply");
Object newInstance = ObjectFactroty.newInstance(cls, null, null);
System.out.println(newInstance);
}
private static void doMethod03(Class<?> cls)
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Long i=new Long(100);
Constructor<?> con = cls.getDeclaredConstructor(Long.class);
con.setAccessible(true);
Object obj = con.newInstance(i);
System.out.println(obj);
}
//private 私有的无参的构造函数
private static void doMethod02(Class<?> cls)
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Constructor<?> con = cls.getDeclaredConstructor();
con.setAccessible(true);
Object obj = con.newInstance();
System.out.println(obj);
}
//有无参且public的构造函数
private static void doMethod01(Class<?> cls) throws InstantiationException, IllegalAccessException {
Object obj = cls.newInstance();
System.out.println(obj);
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println( cls.getClassLoader().getParent());
}
案例2:使用反射通过注解给属性赋值
//声明注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Value{
int value() default 0;
}
//属性私有化,没有构造函数,不使用set方法给属性赋值,把@Value(1)的值赋值给coreSize
class Pool{
@Value(1)
private int coreSize;
}
public class ReflectTest02 {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Class<?> cls=Pool.class;
Field field = cls.getDeclaredField("coreSize");
field.setAccessible(true);
Value value = field.getAnnotation(Value.class);
int i = value.value();
Pool pool=new Pool();
field.setInt(pool, i);
System.out.println(field.getInt(pool));
}
}
//声明对象工厂类,
public class ObjectFactroty {
public static <T>T newInstance(Class<T> cls,Class<?>[] parameterTypes,Object[] objs) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
Constructor<T> con = cls.getDeclaredConstructor(parameterTypes);
con.setAccessible(true);
return con.newInstance(objs);
}
}