反射
- 介绍
能够分析类能力的程序称为反射,Class对象可以表示所有的类型,实际上就是一个泛型类,只是忽略了类型参数。 - Class类主要方法
getClass()—Object类中的getClass方法会返回一个Class类型的实例;
Class.forName()—可以获得类名对应的Class对象;
newInstance()—动态创建对象与forName结合起来,Object o==ClassforName(s).newInstance();
getFields(),getMethods(),getConstructors()—返回公有的成员,包括父类的公有成员;
getDeclareFields()…—可以返回该类定义的私有,保护的成员,但不包括父类的。
getMethod()—取得方法,通过方法名和参数类型取得。Method m=XXX.class.getMethod(“mname”,doule.class)
@Test
public void test1() throws ClassNotFoundException{
Class s=int.class;
Class<String> s1=String.class;
System.out.println(Class.forName("java.lang.Integer"));
}
}
- 利用反射分析类。
在java.lang.reflect中的三个类:Field,Method,Constructor分别描述类的字段,方法和构造器。还有一个Modifier类分析修饰符
都有的方法:
getName—返回名称;
getModifiers()—以整数形式返回修饰符;
setAccessible()—跳过访问权限
Filed类:
getType()—返回一个 Class 对象,表示字段的声明类型。
get()—返回指定对象上此 Field 表示的字段的值。如果该值是一个基本类型值,则自动将其包装在一个对象中。
set()—给字段设置新值
Method类
getReturnType()—方法返回类型
getparameterTypes()—方法参数类型
invoke()—调用方法
Constructor类
getparameterTypes()—方法参数类型
Modifier类
toString()—返回修饰符发字符串
源码如下,很简单的源码。
public static String toString(int mod) {
StringBuilder sb = new StringBuilder();
int len;
if ((mod & PUBLIC) != 0) sb.append("public ");
if ((mod & PROTECTED) != 0) sb.append("protected ");
if ((mod & PRIVATE) != 0) sb.append("private ");
if ((mod & ABSTRACT) != 0) sb.append("abstract ");
if ((mod & STATIC) != 0) sb.append("static ");
if ((mod & FINAL) != 0) sb.append("final ");
if ((mod & TRANSIENT) != 0) sb.append("transient ");
if ((mod & VOLATILE) != 0) sb.append("volatile ");
if ((mod & SYNCHRONIZED) != 0) sb.append("synchronized ");
if ((mod & NATIVE) != 0) sb.append("native ");
if ((mod & STRICT) != 0) sb.append("strictfp ");
if ((mod & INTERFACE) != 0) sb.append("interface ");
if ((len = sb.length()) > 0)
return sb.toString().substring(0, len-1);
return "";
}
该类中还有很多对类的检测的方法
示例
有Person类
public class Person {
private int id;
private String name;
private int age;
//省略get,set...
}
测试
public class TestRef {
public static void main(String[] args) {
TestRef t = new TestRef();
//t.getc();
try {
// t.me();
// t.con();
t.fi();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取类信息
* 1.获取Class对象
* 三种方式
* Xxx.class
* 或者Class.forName("com.xxx.Xxx");需要处理ClassNotFound
* 或者调用某个对象的getClass()方法
* 2.进一步获取其他信息
* 对于私有信息即private修饰,获取需要加上Declared,使用则要加上setAccessible(true);
*/
public void getc() {
Class p = Person.class;
System.out.println();
//类名
System.out.println("仅类名:" + p.getSimpleName() + ";全类名:" + p.getName());
//类的修饰符
Modifier.isAbstract(p.getModifiers());//将类不同的修饰符组合,得到一个int值,如仅用public修饰的值是1,再通过Modifier.isAbstract()方法判断
//包信息
Package pack = p.getPackage();
//父类
Class s = p.getSuperclass();
//实现的接口
Class[] i = p.getInterfaces();
//注解
Annotation[] annotations = p.getAnnotations();
//变量
Field[] fileds = p.getFields();
//方法
Method[] method = p.getMethods();
//构造器
Constructor[] constructors = p.getConstructors();
}
/**
* 构造对象
* 1.获取构造器
* 2.构造对象
*/
public void con() throws Exception {
Class p = Person.class;
Constructor c = p.getConstructor();//,类似的getConstructors()获取所有构造器;getDeclaredConstructors获取所有本类包括私有
Person p1 = (Person) c.newInstance();
}
/**
* 方法相关
* 1.获取方法
* 使用MethodUtil获取或者使用class对象直接获取,返回方法数组,如:[public void com.xxx.Person.setName(java.lang.String),...],或取单个则为method
* 2.调用,需要先获取对象,在通过对象调方法
*/
public void me() throws Exception {
Class p = Person.class;
//-------------方法获取
Method[] m = MethodUtil.getMethods(p);//p.getMethods();数组中包含本类和父类中的所有方法,不包括private修饰
Method[] m1 = p.getDeclaredMethods();//数组中包含本类的所有方法,包括private修饰
Method me = p.getMethod("setAge", int.class);//通过方法名和参数列表获取某个具体方法,非private
Method me2 = p.getDeclaredMethod("setId", int.class);//获取private修饰的方法
Class[] cp = me.getParameterTypes();//获取方法的参数类型,getReturnType()返回值类型
int mod = me.getModifiers();//获取修饰符
//-------------方法调用
Object obj = p.newInstance();//构造对象
//调用public方法
me.invoke(obj, 1);
//调用非public,如private方法
me2.setAccessible(true);
me2.invoke(obj, 1);
}
/**
* 操作属性
*/
public void fi() throws Exception {
Class p = Person.class;
Field[] field = p.getFields();//获取所有字段,getDeclaredField()获取私有的
for (Field f : field) {
f.getName();//获取字段名
f.getType();//字段类型
f.getModifiers();//获取修饰符
f.get(p.newInstance());//获取值。对应的还有set
}
System.out.println(Arrays.toString(field));
}
/**
* 注解相关
* 1.获取值
* 2.相关操作或设置值
*/
public void an() throws Exception {
//获取所有类注解
Class p = Person.class;
Annotation[] ca = p.getAnnotations();
//获取所有方法注解
Method me = p.getMethod("setAge", int.class);
Annotation[] ma = me.getDeclaredAnnotations();
//获取方法参数列表中的注解
Annotation[][] pa = me.getParameterAnnotations();
//获取属性的注解
Field f = p.getField("name");
Annotation[] fa = f.getDeclaredAnnotations();
}