Java反射学习
程序员文章站
2024-01-20 22:31:52
...
Java反射学习
标签(空格分隔): Java
反射定义
反射通常被用来检测和修改运行在Java虚拟机的应用程序的行为。这是一个相对高级的特性,只应该由语言基础很强的开发人员使用。值得说明的是,反射是一种强大的技术特性,可以使应用程序执行一些非常规的操作。
反射入口
- 通过
Object.getClass()
,即对象的实例来获取
public class Car {}
public class Test {
public static void main(String[] args) {
Car car = new Car();
Class clazz = car.getClass();
}
}
- 通过
.class
标识,类来获取
public class Test {
public static void main(String[] args) {
Class clazz = Car.class;
Class cls1 = int.class;
Class cls2 = String.class;
}
}
- 通过
Class.forName
获取
有一些类并不存在与开发环境,只能通过包名.类名
来获取
try {
Class clz = Class.forName("com.frank.test.Car");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class对象内容
- Class名字
/**
* Class为引用时返回二进制形式的字符串,比如“com.example.test.Car”
* Class为基本数据类型,比如int.class,返回关键字int
* Class为基础类型的数组,如int[][][],返回[[[I
*/
Class.getName();
/**
* 去包名限定,如果是数组类型,在后面添加[],比如I[][][]
* 匿名内部类返回空字符串
*/
Class.getSimpleName();
/**
* 官方名,返回包名+simpleName,局部类和匿名内部类返回null
*/
Class.getCanonicalName();
元素类型 | 编码 |
---|---|
boolean | Z |
byte | B |
char | C |
double | D |
float | F |
int | I |
long | J |
short | S |
类或接口 | L类名; |
- Class修饰符
/**
* 返回的是整数
*/
Class.getModifiers() ;
/**
* 返回的是字符串
*/
Modifier.toString(Class.getModifiers());
- 获取Filed
/**
* 获取私有属性
*/
public Field getDeclaredField(String name)
throws NoSuchFieldException,
SecurityException;
/**
* 获取非私有属性,获取不到会向祖先类获取
*/
public Field getField(String name)
throws NoSuchFieldException,
SecurityException;
/**
* 获取所有的属性,但不包括从父类继承下来的属性
*/
public Field[] getDeclaredFields() throws SecurityException {}
/**
* 获取自身的所有的 public 属性,包括从父类继承下来的。
*/
public Field[] getFields() throws SecurityException {
- 获取Method
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
public Method getMethod(String name, Class<?>... parameterTypes)
public Method[] getDeclaredMethods() throws SecurityException
public Method getMethod(String name, Class<?>... parameterTypes)
/**
* 获取构造方法
*/
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
public Constructor<T> getConstructor(Class<?>... parameterTypes)
public Constructor<?>[] getDeclaredConstructors() throws SecurityException
public Constructor<?>[] getConstructors() throws SecurityException
Field操控
- 获取Field类型和修饰符类型
/**
* 能够获取到泛型,更详细
*/
public Type getGenericType() {}
public Class<?> getType() {}
/**
* 能够获取修饰符
*/
public int getModifiers() {}
- Field内容读取和赋值
有一系列setXXX(Object object, xxx value)
和getXXX(Object object)
函数可以调用
Object是指定要读哪个实例
另外如果访问private修饰的成员,会抛异常,要访问修改权限即可
field.setAccessible(true);
Method操控
- 获取内容
/**
* 获取方法名
*/
method.getName();
/**
* 获取方法参数等等。。。
*/
method.getParameters();
- 执行方法
/**
* 第一个参数是对象实例,如果是静态方法填null
* 第二个动态参数是方法的参数列表
* 返回的对象是Object,实际执行要进行强制转换
*/
public Object invoke(Object obj, Object... args) {}
Constructor操控
两种方法创建对象实例,推荐使用后面一种
Class.newInstance();
Constructor.newInstance()
反射中的数组
- 获取类型
Class里有一个方法判断是不是数组类型
public native boolean isArray();
可以通过getName()
和getComponentType()
获取数组类型和数组里的元素类型
- 动态创建数组
通过Array.newInstance()
方法,第一个参数数组元素类型,后面动态参数是维度大小
public static Object newInstance(Class<?> componentType, int... dimensions)
throws IllegalArgumentException, NegativeArraySizeException {}
- 读取和赋值
public void set(Object obj,
Object value)
throws IllegalArgumentException,
IllegalAccessException;
public Object get(Object obj)
throws IllegalArgumentException,
IllegalAccessException;
反射中的枚举
操控枚举,枚举的获取和设定和Fieled一样
// 用来判定 Class 对象是不是枚举类型
Class.isEnum()
// 获取所有的枚举常量
Class.getEnumConstants()
// 判断一个 Field 是不是枚举常量
java.lang.reflect.Field.isEnumConstant()
上一篇: 前备知识 -- 使用canvas制作动画