前言:java反射1,本章总结了反射概念、反射的方法及实例等
反射概念
类加载器根据一个类的全限定名来读取此类的二进制字节流到JVM内部,并存储在运行时内存区的方法区,然后将其转换为一个与目标类型对应的java.lang.Class对象实例
Java的反射利用加载到JVM中的.class文件来进行操作。.class文件中包含java类的所有信息,所以在运行状态中,使用Java反射对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。
总结说:反射就是把java类中的各种成分映射成一个个的Java对象,并且可以进行操作,即方法(Method类)、属性(Filed类)、构造器(Constructor类)等等都是类
反射类
常用方法
获取类的 Class 对象实例
- 使用 Class.forName(“classpath”)
1
| Class clz = Class.forName("java.lang.String");
|
1
| Class clz = String.class;
|
1 2
| String str = new String("Hello"); Class clz = str.getClass();
|
获取类属性、方法、构造器
1 2 3 4 5 6 7 8 9 10 11
| getFields()
getDeclaredFields()
getMethods()
getDeclaredMethods()
|
isInstance
关键字instanceof或者isInstance()方法用于判断是否为某个类的实例
通过反射创建类对象
1 2
| 1. 通过 Class 对象的 newInstance() 方法 1. getConstructor()获取构造器dui, Constructor 对象的 newInstance() 方法
|
实例
1 2 3 4 5 6 7 8 9
| getName():获得类的完整名字 getFields():获得类的public类型的属性 getDeclaredFields():获得类的所有属性。包括private 声明的和继承类 getMethods():获得类的public类型的方法 getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类 getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型 getConstructors():获得类的public类型的构造方法 getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型 newInstance():通过类的不带参数的构造方法创建这个类的一个对象
|
Student.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| public class Student { public String className; private String id; private String name; private String college; public Student() {}; public Student(String id, String name, String college) { this.id = id; this.name = name; this.college = college; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCollege() { return college; } public void setCollege(String college) { this.college = college; } public static void function1(){ System.out.println("function1"); } public void function2(Student student){ System.out.println("id: "+student.id+" name: "+student.name+" college: "+student.college); } private void function3(){ System.out.println("function3"); } private Boolean function4(){ System.out.println("function4"); return true; } }
|
Test.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;
public class Test {
public static void main(String[] args) {
try { String className = "test.Student"; Class<?> c = Class.forName(className); System.out.println("\ngetDeclaredFields()\n"); for(int i=0;i<c.getDeclaredFields().length;i++) { System.out.println(c.getDeclaredFields()[i]); } System.out.println("\ngetFields()\n"); for(int i=0;i<c.getFields().length;i++) { System.out.println(c.getFields()[i]); } System.out.println("\ngetDeclaredMethods()\n"); for(int i=0;i<c.getDeclaredMethods().length;i++) { System.out.println(c.getDeclaredMethods()[i]); } System.out.println("\ngetMethods()\n"); for(int i=0;i<c.getMethods().length;i++) { System.out.println(c.getMethods()[i]); } Constructor<?> constructor =c.getConstructor(String.class,String.class,String.class); Object obj1 = c.newInstance(); Object obj2 = constructor.newInstance("1","2","3"); Student student = (Student)obj1; student.function2((Student)obj2); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
|
私有属性
反射机制中可以获取private成员的值,但是要通过设置(setAccessible(true))进行暴力反射,解除权限。
1 2 3 4 5
| Field[] f = obj.getDeclaredFields(); for(Field field : f){ field.setAccessible(true); System.out.println(field.getName()+":"+field.get(obj.newInstance())); }
|