反射:reflect
Class 类
Field 属性
Method 方法
Constructor 构造方法
package 包
Annotation 注解,可以放在类/属性/方法/构造方法上面,可以放在参数的前面
1.获取Class的三种方式
try {
System.err.println(Class.forName("java.lang.String"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.err.println(String.class);
System.err.println(new String().getClass());
2.Class下的常用方法
2.1 返回此类或接口以整数编码的 Java 语言修饰符。
int getModifiers()
Class clazz = String.class;
int k = clazz.getModifiers();
System.out.println(k);
2.2 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
String getName()
Class clazz = String.class;
System.out.println(clazz.getName());
2.3 返回源代码中给出的底层类的简称。
String getSimpleName()
Class clazz = String.class;
System.out.println(clazz.getSimpleName());
2.4 获取此类的包
Package getPackage()
Class clazz = String.class;
System.out.println(clazz.getPackage().getName());
2.5 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
Class<? super T> getSuperclass()
Class clazz = String.class;
System.out.println(clazz.getSuperclass());
demo 获取ArrayList的所有父类
Class clazz = ArrayList.class;
while ((clazz = clazz.getSuperclass())!=null){
System.out.println(clazz);
}
2.6 确定此对象所表示的类或接口实现的接口。
Class<?>[] getInterfaces()
Class clazz = ArrayList.class;
Class[] classes = clazz.getInterfaces();
for (Class c: classes) {
System.out.println(c.getName());
}
2.7 创建此 Class 对象所表示的类的一个新实例。
调用无参数的构造方法创建对象,如果没有无参数的构造方法,会抛出异常"InstantiationException"
"InstantiationException"产生原因
当应用程序试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常。实例化失败有很多原因,包括但不仅限于以下原因:
类对象表示一个抽象类、接口、数组类、基本类型、void
类没有非 null 构造方法
T newInstance()
Class clazz = Person.class;
try {
Object o = clazz.newInstance();
System.out.println(o);
}catch (Exception e) {
e.printStackTrace();
}
2.8 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。
只能找到自己类和父类的public属性
参数的属性名不存在时,会抛出异常“NoSuchFieldException”
"NoSuchFieldException"产生原因
类不包含指定名称的字段时产生的信号。
Field getField(String name)
Class clazz = Person.class;
try {
Field field = clazz.getField("name");
System.out.println(field);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
2.9 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
只能找到自己类和父类的public属性
Field[] getFields()
Class clazz = Person.class;
try {
Field[] fields = clazz.getFields();
for (Field f : fields) {
System.out.println(f);
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
2.10 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。
只能找到自己类的所有属性,任何修饰符修饰的
Field getDeclaredField(String name)
try {
String str = new String("abc");
System.out.println(str.hashCode()+"-"+str);
Class clazz = str.getClass();
Object o = clazz.newInstance();
Field filed = clazz.getDeclaredField("value");
filed.setAccessible(true);
char[] arr = (char[])filed.get(str);
arr[0] = '1';
arr[1] = '2';
arr[2] = '3';
System.out.println(str.hashCode()+"-"+str);
} catch (Exception e) {
e.printStackTrace();
}
2.12 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
只能找到自己类的所有属性,任何修饰符修饰的
Field[] getDeclaredFields()
2.13 返回一个 或一组Method 对象
@Test
public void test1() throws Exception {
Class clazz = Person.class;
Method method1 = clazz.getMethod("toString");
Method[] method2 = clazz.getMethods();
Method method3 = clazz.getDeclaredMethod("privateXxx");
Method[] method4 = clazz.getDeclaredMethods();
}
2.13 返回一个 或一组Constructor 对象
@Test
public void test1() throws Exception {
Class clazz = Person.class;
Constructor cons = clazz.getConstructor();
Constructor cons2 = clazz.getConstructor(String.class);
cons.newInstance();
cons2.newInstance("张三");
Constructor cons3 = clazz.getDeclaredConstructor(int.class);
cons3.setAccessible(true);
cons3.newInstance(1);
Constructor[] cons4 = clazz.getConstructors();
Constructor[] cons5 = clazz.getDeclaredConstructors();
}