目录
一、定义
二、用途
三、反射基本信息
四、反射相关的类
五、反射示例
六、反射的优点和缺点
一、定义
Java的反射机制是运行时的状态,可以通过反射来调用类里面的属性和方法,私有的属性和方法也可以调用,也可以对它们进行修改。
二、用途
(1)、在第三方应用开发过程,经常会遇到私有的成员变量和方法或是只对系统应用开放,这式就能用反射机制拿到这些私有的成员变量和方法。
(2)、开发各种通用框架。
三、反射基本信息
Java程序中许多对象在运行时会两种类型,一种是编译时类型,一种运行时类型,比如:
Person p = new Student(); 这种情况下,p在编译时的类型是Person,在运行时是Student,程序在运行时需要知道它的类型和对象,Java的反射程序可以判断该对象和类属于哪一类。
四、反射的相关类
(1)、获得类相关的方法
(2)、获得类中属性的方法
(3)、获得类中注解的方法
(4)、获得类中构造器相关方法
(5)、获得类中方法的方法
五、反射的示例
(一)、获得class对象的三种方式,第一种最常用
我们在创建一个包demo1,里面再创建一个Student类,如图
Student类代码:
class Student{//私有属性nameprivate String name = "bit";//公有属性agepublic int age = 18;//不带参数的构造方法public Student(){System.out.println("Student()");}private Student(String name,int age) {this.name = name;this.age = age;System.out.println("Student(String,name)");}private void eat(){System.out.println("i am eat");}public void sleep(){System.out.println("i am sleep");}private void function(String str) {System.out.println(str);} @Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';} }
代码示例:
public class Test {public static void main(String[] args) {//获得class对象的三种方式//第一种try {Class.forName("demo1.Student");} catch (ClassNotFoundException e) {e.printStackTrace();}//第二种Class<?> c2 = Student.class;//第三种Student student = new Student();Class c3 = student.getClass();}
}
(二)、反射的使用
(1)、创建对象
代码示例:
public class Test {public static void main(String[] args) {//获得class对象的三种方式//第一种try {Class.forName("demo1.Student");} catch (ClassNotFoundException e) {e.printStackTrace();}//第二种Class<?> c2 = Student.class;//第三种Student student = new Student();Class c3 = student.getClass();}
}
拿到Student类的对象
//第一种try {Class<?>ClassStudent = Class.forName("demo1.Student");Student student = (Student)ClassStudent.newInstance();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}
(2)、反射私有的构造方法
代码示例:
public static void reflectNewInstance() {//反射私有的构造方法try {//先拿到一个类Class<?> classStudent = Class.forName("demo1.Student");//调用构造方法Constructor<?> constructor = classStudent.getDeclaredConstructor(String.class, int.class);//私有的属性name需要你确认才能更改constructor.setAccessible(true);Student student = (Student) constructor.newInstance("xiaoming", 15);System.out.println(student);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}
调用这个代码后现象:
(3)、反射私有属性
代码示例:
public static void reflectPrivateField() {//反射私有属性try {Class<?> classStudent = Class.forName("demo1.Student");Field field = classStudent.getDeclaredField("name");field.setAccessible(true);Student student = (Student)classStudent.newInstance();field.set(student, "caocao");System.out.println(student);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchFieldException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}
调用这个代码后现象:
(4)、反射私有方法
代码示例:
public static void reflectPrivateMethod() {//反射私有方法try {Class<?> classStudent = Class.forName("demo1.Student");Method method = classStudent.getDeclaredMethod("function");method.setAccessible(true);Student student = (Student)classStudent.newInstance();method.invoke(student, "我是一个反射参数");} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}
六、反射的优点和缺点
优点:1、对任意类的成员变量或方法都能调用,对于任意一个对象,都能调用它的方法,封装就不起到作用了。
2、运用于很多流行的框架(Struts、Hibernate、Spring 等等)。
3、增强程序的灵活性和扩展性。
缺点:1、效率问题,使用反射程序会导致程序效率低。
2、因功能太过强大,维护起来也比较麻烦,反射代码相对于普通代码也更复杂。