目录
1.反射机制是什么?
2.反射机制能干什么?
3.反射相关的类
编辑
4.Class类(反射机制的起源 )
5.反射机制相关的API
1.(重要)常用获得类相关的方法
2.常用获得类中属性相关的方法(以下方法返回值为Field相关
3.(了解)获得类中注解相关的方法
4.(重要)获得类中构造器相关的方法(以下方法返回值为Constructor相关)
编辑 5.(重要)获得类中方法相关的方法(以下方法返回值为Method相关)
6.反射示例
1.获得Class对象的三种方式
2.反射的使用
1.产生对象
方法一:调用类的无参构造,且该构造方法必须是public权限!!
方法二:通过Constructer类来调用构造方法产生对象
2.通过反射操作类中的方法
7、反射优点和缺点
1.反射机制是什么?
Java反射是指在程序运行期间,可以动态的获取到任意一个类的相关信息,并且调用任意对象的属性或方法,这种动态获取类的信息的方式和动态调用对象方法的功能称之为Java对象的反射机制
Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个实例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类
2.反射机制能干什么?
通过Java语言中的反射机制可以操作字节码文件,还可以操作代码片段(class文件)
Java反射机制的相关类都在Java.long.reflect.*;包下
3.反射相关的类
4.Class类(反射机制的起源 )
Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为 一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个实 例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成 为一个动态的类 .
5.反射机制相关的API
1.(重要)常用获得类相关的方法
2.常用获得类中属性相关的方法(以下方法返回值为Field相关
- getField(String name) :获得某个公有的属性对象
- getFields() :获得所有公有的属性对象
- getDeclaredField(String name) :获得某个属性对象
- getDeclaredFields() :获得所有属性对象
3.(了解)获得类中注解相关的方法
4.(重要)获得类中构造器相关的方法(以下方法返回值为Constructor相关)
5.(重要)获得类中方法相关的方法(以下方法返回值为Method相关)
- getMethod(String name, Class...<?> parameterTypes) :获得该类某个公有的方法
- getMethods() :获得该类所有公有的方法
- getDeclaredMethod(String name, Class...<?> parameterTypes) :获得该类某个方法
- getDeclaredMethods() :获得该类所有方法
6.反射示例
1.获得Class对象的三种方式
第一种 ,使用 Class.forName(" 类的全路径名 "); 静态方法。前提:已明确类的全路径名。第二种 ,使用 类名称.class 方法。说明:仅适合在编译前就已经明确要操作的 Class第三种 ,使用类任意对象的 getClass() 方法
package com.example.reflect.model;public class Student {// 共有属性nameprivate String name;// 私有属性ageprivate Integer age;// 不带参数的构造方法public Student() {}// 带参数的构造方法private Student(String name, Integer 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 pig");}private void function(String str) {System.out.println(str);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
class TeatReflect {public static void main(String[] args) {/*** 1.通过getClass获取Class对象*/Student student = new Student();Class c = student.getClass();/*** 2.直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高* 这说明任何一个类都有一个隐含的静态成员变量 class*/Class c2 = Student.class;/*** 3、通过 Class 对象的 forName() 静态方法来获取,用的最多,* 但可能抛出 ClassNotFoundException 异常*/Class c3 = null;try {c3 = Class.forName("com.example.reflect.model.Student");} catch (ClassNotFoundException e) {e.printStackTrace();}//一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的//c1,c2,c3进行 equals 比较,发现都是trueSystem.out.println(c.equals(c2));System.out.println(c3.equals(c2));System.out.println(c3.equals(c));}
}
2.反射的使用
1.产生对象
方法一:调用类的无参构造,且该构造方法必须是public权限!!
// 产生对象public static void reflectNewInstance() {try {Class<?> classStudent = Class.forName("com.example.reflect.model.Student");// 调用的是无参构造,且必须是公有的Object objectStudent = classStudent.newInstance();Student student = (Student) objectStudent;System.out.println("获得学生对象:"+student);} catch (Exception e) {e.printStackTrace();}}
如果使私有的无参构造那么就会报错了,就像下面这样:
此时我们通过无参构造去获取对象:
方法二:通过Constructer类来调用构造方法产生对象
Constructer类就是Java中利用反射操作构造方法的类
- getConstructor(参数):获取该类的所有public 权限的构造方法
- getDeclareConstructor:获取该类的所有权限的构造方法,包括私有权限
// 产生对象public static void reflectNewInstance2() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {// 获取Class对象Class<Student> classStudent = Student.class;// 获得所有的构造方法Constructor<Student>[] constructors = (Constructor<Student>[]) classStudent.getDeclaredConstructors();System.out.println(Arrays.toString(constructors));// 获取私有的有参构造Constructor<Student> constructor = classStudent.getDeclaredConstructor(String.class,Integer.class);// 破坏封装性·constructor.setAccessible(true);// 通过私有构造方法创建对象Student student = constructor.newInstance("锦鲤",18);System.out.println(student);}
反射可以获得所有的不论公有私有的方法和属性,他会破坏封装性,只在当前JVM进程中可见
2.通过反射操作类中的方法
// 操作方法public static void reflectByMethod() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {// 获取Class对象Class<Student> classStudent = Student.class;Method[] methods = classStudent.getDeclaredMethods();System.out.println(Arrays.toString(methods));// 通过反射来调用普通方法和静态方法// 调用普通方法首先要产生对象Student student = classStudent.newInstance();// 通过反射拿到fun方法的反射方法Method methodFun = classStudent.getMethod("fun", String.class);// 通过Method反射对象调用fun方法, 传入调用该方法的对象以及需要传入的参数methodFun.invoke(student, "锦鲤");// 调用静态方法Method methodTest = classStudent.getMethod("test");methodTest.invoke(null);}
7、反射优点和缺点
- 1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
- 2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
- 3. 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。
- 1. 使用反射会有效率问题。会导致程序效率降低。具体参考这里:http://www.imooc.com/article/293679
- 2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂
反射的讲解就到这里啦!
下篇博客见~