Java反射获取类的全部属性和全部方法
如下:
获取该类Class对象返回Class<?>,也可用 对象.getClass获得
Class<?> clazz = Class.forName("com.c.butter.Unbinder");
Class<? extends List> clazz = list.getClass();
Class<? extends int[]> clazz = a.getClass();
判断是否是java基本数据类型(boolean、char、byte、short、int、long、float、double)
boolean primitive = clazz.isPrimitive();
判断clazz1是不是clazz的子类或者子接口
clazz.isAssignableFrom(clazz1);
获取父类、接口实现的、当前类所有public方法,
Method[] methods = clazz.getMethods();
获取当前类声明的所有方法、接口实现的方法,但是不包含父类继承的方法
Method[] declaredMethods = clazz.getDeclaredMethods();
获取当前类所有public属性、实现接口的属性、父类属性
Field[] fields = clazz.getFields();
获取当前类声明的所有属性,接口实现的属性,但不包括继承的父类属性
Field[] declaredFields = clazz.getDeclaredFields();
获取name
String simpleName = clazz.getSimpleName();
String name = clazz.getName();
//获取典范(canonical)的名字
String canonicalName = clazz.getCanonicalName();
//MainActivity 当clazz是数组Class时 int[]
Log.d("simpltName", simpleName);
//com.c.t.MainActivity 当clazz是数组Class时 [I
Log.d("name", name);
//com.c.t.MainActivity 当clazz是数组Class时 int[]
Log.d("canonicalName", canonicalName);
返回底层的直接封闭类,如果底层类是顶级类,方法返回{@code null},比如某个被使用的注解,调取此方法,返回使 用它的地方所被直接包裹的类`
Class<?> enclosingClass = clazz.getEnclosingClass();
Constructor<?> enclosingConstructor = clazz.getEnclosingConstructor();
Class<?> componentType = clazz.getComponentType();
//根据获取的Class对象new出实例
Object o = clazz.newInstance();
Object o1 = clazz.getConstructor().newInstance();
接下来我们以Test.java为例,尝试给获取到的属性赋值
Class<?> klazz = Class.forName("com.c.t.Test");
Object test = klazz.newInstance();
//这个赋值可以把对象test的a赋值为10
Field a1 = klazz.getField("a");
a1.set(test, 10);
但是接下来我们看看我们给 d 赋值,打印出来d并没有被赋值为5,因为他是private修饰的
Field d = klazz.getField("d");
d.set(test, 5);
//那么怎么给私有属性赋值呢,java给我们提供了方法
Field d1 = klazz.getField("d");
//设置属性为可接受修改状态
d1.setAccessible(true);
d1.set(test, 5);
d1.setAccessible(false);
这个时候我们打印出来的d值是5
Java Field.getType():返回一个Class对象,获取属性声明时类型对象,它标识了此Field对象所表示字段的声明类型
Class<?> type = a1.getType();
getGenericType() : 返回属性声的Type类型
Type genericType = a1.getGenericType();
getType() 和 getGenericType()的区别 :
1.首先是返回的类型不一样,一个是Class对象一个是Type接口。
2.如果属性是一个泛型,从getType()只能得到这个属性的接口类型。但从getGenericType()还能得到这个泛型的参数类型。
3.getGenericType()如果当前属性有签名属性类型就返回,否则就返回 Field.getType()。
用反射创建数组,并填充数据
array类提供静态方法来动态创建和访问Java数组。
// 填充数组
private static void fillArray(Object array) {
int length = Array.getLength(array);
Random generator = new Random(System.currentTimeMillis());
for (int i = 0; i < length; i++) {
int random = generator.nextInt();
//Sets the value of the indexed component of the specified
//array object to the specified int value.
Array.setInt(array, i, random);
}
}
private static void displayArray(Object array) {
int length = Array.getLength(array);
for (int i = 0; i < length; i++) {
int value = Array.getInt(array, i);
System.out.println("Position: " + i + ", value: " + value);
}
}
public class Test {
public int a;
public String b;
public float c;
private int d;
private String e;
public Test t;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public float getC() {
return c;
}
public void setC(float c) {
this.c = c;
}
public int getD() {
return d;
}
public void setD(int d) {
this.d = d;
}
public String getE() {
return e;
}
public void setE(String e) {
this.e = e;
}
}