Java反射
反射:将类的各个组成部分封装为其他对象
类文件经过编译形成class文件,class文件通过类加载器加载进内存,形成Class对象
- 可以在程序运行过程中,操作这些对象。
- 可以解耦,提高程序的可扩展性。
Class对象
Class类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class
对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象。基本的 Java
类型(boolean、byte、char、short、int、long、float
和double)和关键字void也表示为Class对象。
获取Class对象
-
Class.forName("全类名"):将字节码文件加载进内存,返回Class对象 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
-
类名.class:通过类名的属性class获取 多用于参数的传递
-
对象.getClass():getClass()方法在Object类中定义着。 多用于对象的获取字节码的方式
示例:创建一个Student对象,通过三种方式获得它的Class对象
public class Student { private String name; public int age; public Student(){ } public Student(String name,int age){ this.age = age; this.name = name; } private void priMethod(){ System.out.println("priMethod..."); } public String pubMethod(String gender){ return "pubMethod"+gender; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }public static void main(String[] args) throws Exception { //1. Class.forName("全类名") Class stuClass1 = Class.forName("com.codesy.reflect.Student"); System.out.println(stuClass1); //2.类名.class Class stuClass2 = Student.class; System.out.println(stuClass2); //3.对象.getClass Student stu = new Student(); Class stuClass3 = stu.getClass(); System.out.println(stuClass3); //三种方式获得Class对象均为同一个 System.out.println(stuClass1 == stuClass2 && stuClass1 == stuClass3); }输出结果:
class com.codesy.reflect.Student
class com.codesy.reflect.Student
class com.codesy.reflect.Student
true
Class对象方法
获取功能:
1. 获取成员变量们
* Field[] getFields() :获取所有public修饰的成员变量
* Field getField(String name) 获取指定名称的 public修饰的成员变量
* Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
* Field getDeclaredField(String name)
2. 获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>... parameterTypes)
* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
3. 获取成员方法们:
* Method[] getMethods()
* Method getMethod(String name, 类<?>... parameterTypes)
* Method[] getDeclaredMethods()
* Method getDeclaredMethod(String name, 类<?>... parameterTypes)
4. 获取全类名
* String getName()
5. Annotation[] getAnnotations()
返回此元素上存在的所有注释。
6. URL getResource(String name)
查找带有给定名称的资源。
7. InputStream getResourceAsStream(String name)
查找具有给定名称的资源,返回输入字节流
判断功能:
boolean isArray()
判定此 Class 对象是否表示一个数组类。
boolean isAssignableFrom(Class<?> cls)
判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。
boolean isEnum()
当且仅当该类声明为源代码中的枚举时返回 true。
boolean isInstance(Object obj)
判定指定的 Object 是否与此 Class 所表示的对象赋值兼容。
boolean isInterface()
判定指定的 Class 对象是否表示一个接口类型。
boolean isLocalClass()
当且仅当底层类是本地类时返回 true。
boolean isMemberClass()
当且仅当底层类是成员类时返回 true。
创建对象:
T newInstance()
创建此 Class 对象所表示的类的一个新实例。
Field对象
Field:成员变量
* 操作:
1. 设置值
* void set(Object obj, Object value)
2. 获取值
* get(Object obj)
3. 忽略访问权限修饰符的安全检查
* setAccessible(true)
4. Class<?> getType()
返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
测试:
Field[] fields = stuClass1.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
Class type = field.getType();
System.out.println(name+" "+type);
}
输出结果:
name class java.lang.String
age int
Constructor:构造方法
* 创建对象:
* T newInstance(Object... initargs)
* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
String getName()
以字符串形式返回此构造方法的名称。
示例:
Constructor[] constructors = stuClass1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName();
System.out.println(name);
}
Constructor con = stuClass1.getDeclaredConstructor(String.class, int.class);
//创建对象
Object stu = con.newInstance("张三", 18);
System.out.println(stu);
输出结果
com.codesy.reflect.Student
com.codesy.reflect.Student
Student{name=‘张三’, age=18}
Method:方法对象
* 执行方法:
* Object invoke(Object obj, Object... args)
* 获取方法名称:
* String getName:获取方法名
示例:
Method[] methods = stuClass1.getDeclaredMethods();
for (Method method : methods) {
String name = method.getName();
System.out.println(name);
}
Method pubMethod = stuClass1.getDeclaredMethod("pubMethod", String.class);
//执行pubMethod方法,返回“pubMethod李四”
String name = (String)pubMethod.invoke(stu,"李四");
System.out.println(name);
输出结果
toString
priMethod
pubMethod
pubMethod李四
1万+

被折叠的 条评论
为什么被折叠?



