------- android培训、java培训、期待与您交流! ----------
Reflection - Java的反射机制
反射就是把Java类中的各个成分映射成相应的Java类。
很多优秀框架的实现,都大量运用了Java的反射机制。
-------------------------------------------------------------------
Class类
Class类,通俗的理解,就是一个可以操作所有Java类的类。
Class类对象包含某个类的名称,构造器,属性,方法及返回值等信息的操作。
Class对象,是一个Java类的字节码
3种获得字节码的方法:
1.某类已被加载过,可直接从内存中获取:类名.class
2.根据已存在的类对象获取:new Date().getClass();
2.根据指定的类名,使用类加载器加载:Class.forName("java.util.Date");
Class的常用方法
获取某类的类型:
SomeClass.class;
SomeObject.getClass();
Class.forName("ClassName");
判断class类型:
isPrimitive() 是否是原始数据类型;
isArray() 是否是数组类型;
int.class == Integer.
TYPE //结果为true
*所有基本数据类型与它们的包装类的类型是一致的
所有Java类都有各自的Class实例对象
Constructor类
此类用于操作某个Java类的构造方法。
Constructor对象的获取:
某类.class.getConstructor(*.class, ..);
Class.newInstance()方法
Constructor cons1 = String.class.getConstructor();
Field类
操作某类的字段Field:获取字段值、修改字段值
public class SomeClass
{
private int x;
public int y;
SomeClass(){}
SomeClass(int x, int y)
{
this.x = x;
this.y = y;
}
public static void main(String[] ages)
{
Constructor cons1 = SomeClass.class.getDeclaredConstructor(int.class, int.class);
SomeClass so = (SomeClass)cons1.newInstance();
SomeClass so = new SomeClass(3, 5);
Field fileY = so.getClass().getFiel("y");
System.out.println(fileY.get(so));
Field fileX = so.getClass().getDeclaredField("x");
fileX.setAccessible(true);
System.out.println(fieldX.get(so));
}
}
Method类
操作某类的方法:
Method m = SomeClass.class.getMethod("test", int.class);
m.invoke(obj, 888);
----------------------------------------------
扩展应用:用反射的方式执行某个类的main方法
Method m = SomeClass.class.getMethod("main", String[].class);
//m.invoke(obj, new Object(){new String[]{}});
m.invoke(obj, (Object)new String[]{"123","xyz","abc"});
Array类 - 对数组类型对象的反射操作
具有相同维数和元素类型的数组,属于同一种类型,即具有相同的Class实例对象。
get
基本类型的一维数组可以被当做Object类型使用,不能当做Object[]数组类型使用。
非基本类型的一维数组,既可以当做Objec类型使用,也可以当做Object[]数组类型使用。
object obj = new String[]{"123","abc","xyz"};
Class<?> clazz = obj.getClass();
if(clazz.isArray()) {
int len = Array.getLength(obj);
for(int i=0; i<len; i++)
{
System.out.println(Array.get(obj, i));
}
} else {
System.out.println(obj);
}
----------------------------------------------
扩展
:List和Set的比较及HashCode分析
当使用哈希表算法的集合存储对象元素,应该重写对象的hashCode方法和equals方法。
当一个元素被存放到集合中,其集合内部区域存放的是对象的哈希值和对象引用。如果没有重写hashCode方法,当实际对象的内部被修改之后,如果想从原集合中删除该对象,那么将无法真正删除,也就是说,此对象所占用的内存将无法释放了。
当重写了hashCode方法后,可能会出现内存泄露的现象。
----------------------------------------------
扩展1: 实现框架的配置功能(类的调用)
从一个properties文件中读取指定property值,然后利用反射来创建对象。
扩展2:解决配置文件的路径问题:
某类.class.getResourceAsStream(String name)
InputStream getResourceAsStream(String name) 根据指定路径返回输入流