反射的理解
-
反射机制(reflection)
Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任何一个对象,都能调用它的任意方法和属性,既然可以拿到,那就可以修改部分类型信息;这种动态获取信息以及动态调用方法的功能称为Java语言的反射机制 -
应用
<1>. 反射最重要的作用是开发各种通用的框架<2>. 在日常的第三方应用开发的过程中,经常遇到某个类的某个成员变量、方法或是私有的或是只对系统应用开发的,这时候就可以用Java反射机制获取私有成员或方法
<3>. 反射基本信息
Java程序中许多对象运行时会有两种类型:运行时类型和编译时类型
程序运行本质是在运行时发现对象的类的真实信息,通过反射机制可以判断出该对象和类属于那些类
反射相关的类
类名 | 用途 |
---|---|
Class类 | 代表类的实体,在运行Java应用程序中表示类的接口 |
Field类 | 代表类的成员变量/类的属性 |
Method类 | 代表类的方法 |
Constructor类 | 代表类的构造方法 |
Class类中的相关方法
方法 | 用途 |
---|---|
getClassLoader() | 获得类的加载器 |
getDeclaredClasses() | 返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有) |
forName(String className) | 根据类名返回类的对象 |
newInstance() | 创建类的实例 |
getName() | 获得类的完整路径名字 |
- 常用获得类中属性相关的方法(返回值为Field相关)
方法 | 用途 |
---|---|
getField(String name) | 获得某个公有的属性对象 |
getFields() | 获得所有公有的属性对象 |
getDeclaredField(String name) | 获得某个属性对象 |
getDeclaredFields() | 获得所有属性对象 |
- 获取类中的构造器相关的方法(返回值为Constructor相关)
方法 | 用途 |
---|---|
getConstructor(Class…<?>parameter Types) | 获得该类中与参数类型匹配的公有构造方法 |
getConstructors() | 获得该类的所有公有构造方法 |
getDeclaredConstructor(Class…<?> parameterTypes) | 获得该类中与参数类型匹配的构造方法 |
getDeclaredConstructors() | 获得该类所有构造方法 |
- 获得类中方法 相关的方法(返回值为Method相关)
方法 | 用途 |
---|---|
getMethod(String name, Class…<?> parameterTypes) | 获得该类某个公有的方法 |
getMethods() | 获得该类所有公有的方法 |
getDeclaredMethod(String name, Class…<?> parameterTypes) | 获得该类某个方法 |
getDeclaredMethods() | 获得该类所有方法 |
反射使用
(1)获得Class对象的三种方式
public static void main(String[] args) throws ClassNotFoundException {
//1.通过Class对象的forName()静态方法获取(用的最多,注意抛异常)
Class<?> c1 = Class.forName("reflectdemo.Student");
}
//2.通过getClass获取class对象
Student student = new Student();
Class<?> c2 = student.getClass();
//3.直接通过 类型.class获取(更安全可靠,程序性能更高)
Class<?> c3 = Student.class;
(2)反射的使用——所有和反射相关的包都在 import.java.lang.reefelect
包下
//1 通过反射创建对象
public static void reflectNewInstance() {
try {
Class<?> c1 = Class.forName("reflectdemo.Student");
Student student = (Student) c1.newInstance();
System.out.println(student);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
//2 反射私有的构造方法,屏蔽内容为获得公有的构造方法
public static void reflectPrivateConstructor() {
try {
Class<?> c1 = Class.forName("reflectdemo.Student");
//注意传入对应的参数
Constructor<?> constructor =
c1.getDeclaredConstructor(String.class, int.class);
//你确定要在类外访问私有方法吗.设置为true后可修改访问权限
constructor.setAccessible(true);
Student student = (Student) constructor.newInstance("xiangyu",22);
System.out.println(student);
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
//3.反射私有属性
public static void reflectPrivateField() {
try {
Class<?> c1 = Class.forName("reflectdemo.Student");
Student student = (Student) c1.newInstance();
//可以修改该属性的值
Field field = c1.getDeclaredField("name");
//访问私有的,提前询问一下是否确定访问
field.setAccessible(true);
field.set(student,"liubang");
System.out.println(student);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
//4. 反射私有方法
public static void reflectPrivateMethod() {
try {
Class<?> c1 = Class.forName("reflectdemo.Student");
Student student = (Student) c1.newInstance();
Method method = c1.getDeclaredMethod("function", String.class);
method.setAccessible(true);
method.invoke(student,"通过反射给你传参");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}//3.反射私有属性
public static void reflectPrivateField() {
try {
Class<?> c1 = Class.forName("reflectdemo.Student");
Student student = (Student) c1.newInstance();
//可以修改该属性的值
Field field = c1.getDeclaredField("name");
//访问私有的,提前询问一下是否确定访问
field.setAccessible(true);
field.set(student,"liubang");
System.out.println(student);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
//4. 反射私有方法
public static void reflectPrivateMethod() {
try {
Class<?> c1 = Class.forName("reflectdemo.Student");
Student student = (Student) c1.newInstance();
Method method = c1.getDeclaredMethod("function", String.class);
method.setAccessible(true);
method.invoke(student,"通过反射给你传参");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
反射优缺点
优点:
- 任意一个类,都可以知道这个类的所有属性和方法;任意一个对象,都可以调用它的任意一个方法
- 增加程序的灵活性和拓展性,降低耦合,提高自适应能力
- 反射应用在好多框架上
缺点:
- 反射因调用好多方法,可能存在效率降低的问题
- 反射技术绕过了源代码的技术,会有维护的问题,并且反射代码比相应直接代码更加复杂
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/119556.html