反射
概念
JAVA程序在运行状态时,能够获取任意一个类的属性和方法;
并且可以创建类的对象实例,调用它的任意属性和方法;
这种动态获取类的信息以及动态调用对象方法的功能称为java的反射机制。
获取Class对象
每个类被系统加载后,系统会为该类生成一个对应的Class对象,通过它可以访问到JAVA虚拟机中的这个类。
我们可以通过三种方式来获取Class的对象
1)通过某个类的class属性
2)通过Class类的forName(String className)静态方法,className为全限定名,比如String的全限定名为java.lang.String
3)通过对象调用Object的getClass()方法
1 package com.java.reflect;
2
3
4 import com.java.model.Student;
5
6 public class ReflectTest {
7 public static void main(String[] args) throws ClassNotFoundException {
8 //1.通过某个类的class属性
9 Class<Student> stu1 = Student.class;
10 System.out.println(stu1);
11
12 //2.通过Class类的forName(String className)静态方法
13 Class<Student> stu2 = (Class<Student>)Class.forName("com.java.model.Student");
14 System.out.println(stu2);
15
16 //3.通过对象调用Object的getClass()方法
17 Class stu3 = new Student().getClass();
18 System.out.println(stu3);
19
20 System.out.println((stu1 == stu2) && (stu2 == stu3) && (stu1 == stu3)); //true
21 }
22 }
获取类的信息
package com.java.reflect;
import com.java.model.Student;
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException {
//1.通过某个类的class属性
Class<Student> stu = Student.class;
System.out.println("1: " + stu);
//2.得到包名
System.out.println("2: " + stu.getPackage());
//3.得到类的全限定名
System.out.println("3: " + stu.getName());
//4.得到类的简称
System.out.println("4: " + stu.getSimpleName());
//5.得到父类,返回表示此Class所表示的实体的超类的Class
System.out.println("5: " + stu.getSuperclass().getSimpleName());
//6.得到接口
System.out.println("6: " + stu.getInterfaces());
System.out.println(" Interfaces:");
Class[] interfArr = stu.getInterfaces();
for(Class interf : interfArr){
System.out.println(" " + interf);
}
}
}
获取构造函数、方法和字段
1 package com.java.reflect;
2
3
4 import java.lang.reflect.Constructor;
5 import java.lang.reflect.Field;
6 import java.lang.reflect.Method;
7
8 import com.java.model.Student;
9
10 public class ReflectTest {
11 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, NoSuchFieldException {
12 System.out.println("1.通过某个类的class属性");
13 Class<Student> stu = Student.class;
14 System.out.println(stu);
15
16 System.out.println("2.获取public修饰的构造器函数");
17 Constructor[] cons = stu.getConstructors();
18 for(Constructor con : cons){
19 System.out.println(con);
20 }
21
22 System.out.println("3.获取指定的public修饰的构造器函数");
23 Constructor con = stu.getConstructor(String.class);
24 System.out.println(con);
25
26 System.out.println("4.获取全部的构造器函数");
27 Constructor[] cons2 = stu.getDeclaredConstructors();
28 for(Constructor con2 : cons2){
29 System.out.println(con2);
30 }
31
32 System.out.println("5.获取包含父类的public修饰的方法");
33 Method[] methods = stu.getMethods();
34 for(Method method : methods){
35 System.out.println(method);
36 }
37
38 System.out.println("6.获取指定的public方法");
39 Method method2 = stu.getMethod("sayName", null);
40 System.out.println(method2);
41
42 System.out.println("7.获取类的所有方法,但是不能获取继承的方法和它实现接口的方法");
43 Method[] methods2 = stu.getDeclaredMethods();
44 for(Method meth : methods2){
45 System.out.println(meth);
46 }
47
48 System.out.println("8.获取public修饰的字段");
49 Field[] fs = stu.getFields();
50 for(Field f : fs){
51 System.out.println(f);
52 }
53
54 System.out.println("9.获取特定字段");
55 Field f2 = stu.getField("name");
56 System.out.println(f2);
57
58 System.out.println("10.获取不限定名称的全部字段,只对当前类有效");
59 Field[] fields = stu.getDeclaredFields();
60 for(Field field : fields){
61 System.out.println(field);
62 }
63 }
64 }
getDeclaredMethod
私有方法直接访问会报错->setAccessible(true)
可以获取类的所有方法,但是不能获取继承的方法和它实现接口的方法
getMethod
只能获取public方法,但是可以获取继承的方法和它实现接口的方法
如何获取私有类型的field > getDeclaredField
如何获取类的构造函数
总结
反射就是把java中的各种成分映射成一个个的java对象,如Class,Method,Field