主页 > IT业界  > 

Java反射

Java反射
一. 概述

        反射:加载类,并允许以编程的方式解剖类中的各个成分(成员变量、方法、构造器等等)

二. 获取类的字节码:Class对象

        三种方式:

        1. Class c1 =  类名.class:

        2. 调用Class提供的方法:public static Class forName(String package)

        3. Object提供的方法:public Class getClass(); Calss3 = 对象.getClass()

public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public static void main(String[] args) throws ClassNotFoundException { Class c = Student.class; System.out.println(c.getName());//全类名 System.out.println(c.getSimpleName());//简名 Student Class c2 = Class.forName( "com.wyyzs.d01.Student"); System.out.println(c2.getName()); System.out.println(c2.getSimpleName()); Student student = new Student(); Class c3 = student.getClass(); System.out.println(c3.getName()); System.out.println(c3.getSimpleName()); } 三. 获取类的构造器         获取类的构造器 Class提供了从类中获取构造器的方法说明Constructor<?>[] getConstructors()获取全部构造器(只能获取public 修饰的)Constructor<?>[] getDeclaredConstructors()获取全部构造器(只要存在就能拿到)Constructor<?>[] getConstructor (Class<?>... parameterTypes)获取某个构造器(只能获取public修饰的)Constructor<?>[] getDeclaredConstructor(Class<?>... parameterTypes)获取某个构造器(只要存在就能拿到)         获取类构造器的作用

                初始化对象返回

Constructor提供的方法

说明T newInstance(Object... initargs)调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回public void setAccessible(boolean flag)设置true,表示禁止检查访问控制(暴力反射) public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } private Student(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } } @Test public void test1() throws Exception { Class studentClass = Student.class; //Constructor<?>[] getConstructors() 获取全部构造器(只能获取public 修饰的) Constructor[] constructors = studentClass.getConstructors(); for(Constructor constructor : constructors){ System.out.println(constructor.getName() + " " + constructor.getParameterTypes().length); } System.out.println("------------------------"); //Constructor<?>[] getDeclaredConstructors() 获取全部构造器(只要存在就能拿到) Constructor[] constructors2 = studentClass.getDeclaredConstructors(); for(Constructor constructor : constructors2){ System.out.println(constructor.getName() + " " + constructor.getParameterTypes().length); } System.out.println("------------------------"); //Constructor<?>[] getConstructor(Class<?>... parameterTypes) 获取某个构造器(只能获取public修饰的) //无参 Constructor constructors3 = studentClass.getConstructor(); System.out.println(constructors3.getName() + " " + constructors3.getParameterTypes().length); //有参 Constructor constructors4 = studentClass.getConstructor(String.class, int.class); System.out.println(constructors4.getName() + " " + constructors4.getParameterTypes().length); System.out.println("------------------------"); //Constructor<?>[] getDeclaredConstructor(Class<?>... parameterTypes) 获取某个构造器(只要存在就能拿到) //无参 Constructor constructors5 = studentClass.getDeclaredConstructor(); System.out.println(constructors5.getName() + " " + constructors5.getParameterTypes().length); //有参 Constructor constructors6 = studentClass.getDeclaredConstructor(String.class); System.out.println(constructors6.getName() + " " + constructors6.getParameterTypes().length); Constructor constructors7 = studentClass.getDeclaredConstructor(String.class, int.class); System.out.println(constructors7.getName() + " " + constructors7.getParameterTypes().length); //T newInstance(Object... initargs) 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回 //public void setAccessible(boolean flag) 设置true,表示禁止检查访问控制(暴力反射) //调 constructors6 私有构造器 会报权限异常 此时 使用 setAccessible 设置true,表示禁止检查访问控制(暴力反射) /* Student student = (Student) constructors6.newInstance(); System.out.println(student);*/ constructors6.setAccessible(true); Student student2 = (Student) constructors6.newInstance("卡莎"); System.out.println(student2); Student student3 = (Student) constructors7.newInstance("卡莎", 18); System.out.println(student3); } 四. 获取类的成员变量         从类中获取成员变量的方法 Class提供了从类中获取成员变量的方法说明public Field[] getFields()获取类全部的成员变量(只能获取public修饰的),使用较少public Field[] getDeclaredFields()获取类的全部成员变量(只要存在就能拿到)public Field getField(String name)获取类的某个成员变量(只能获取public修饰的)public Field getDeclaredField(String name)获取类的某个成员变量(只要存在就能获取)         获取到成员变量的作用

                获取到成员变量的作用是赋值、取值

方法说明void set(Object obj, Object value)赋值Object get(Object obj)取值public void setAccessible(boolean flag)设置为ture,表示禁止检查访问控制 public class Dog { private String name; private int age; public static int o; public static final String C = "狗狗"; public Dog() { } public Dog(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } } @Test public void Test3_Field() throws NoSuchFieldException { //获取类的成员变量 //得到类的Class对象 Class dog = Dog.class; //public Field[] getFields() 获取类全部的成员变量(只能获取public修饰的) Field[] fields = dog.getFields(); for(Field f : fields){ System.out.println(f.getName() + "---->" + f.getType()); } System.out.println("-------------------------------------"); //public Field[] getDeclaredFields() 获取类的全部成员变量(只要存在就能拿到) Field[] fields1 = dog.getDeclaredFields(); for(Field f : fields1){ System.out.println(f.getName() + "---->" + f.getType()); } System.out.println("-------------------------------------"); //public Field getField(String name) 获取类的某个成员变量(只能获取public修饰的) Field field = dog.getField("o"); System.out.println(field.getName() + "---->" + field.getType()); Field field2 = dog.getField("C"); System.out.println(field2.getName() + "---->" + field2.getType()); System.out.println("-------------------------------------"); //public Field getDeclaredField(String name) 获取类的某个成员变量(只要存在就能获取) Field field3 = dog.getDeclaredField("name"); System.out.println(field3.getName() + "---->" + field3.getType()); Field field4 = dog.getDeclaredField("age"); System.out.println(field4.getName() + "---->" + field4.getType()); System.out.println("==================================="); //void set(Object obj, Object value) 赋值 Dog dog1 = new Dog(); //field3->name 为私有 赋值会抛异常 需要 void setAccessible(boolean flag) 设置为ture,表示禁止检查访问控制 //public void setAccessible(boolean flag) 设置为ture,表示禁止检查访问控制 field3.setAccessible(true); field3.set(dog1, "拉布拉多"); System.out.println(dog1); //Object get(Object obj) 取值 //field3->name String name = (String) field3.get(dog1); System.out.println(name); } 五. 获取类的成员方法          从类中获取成员方法 Class提供了从类中获取成员方法说明Method[] getMethods()获取类的全部成员方法(只能获取public 修饰的) 使用较少Method[] getDeclaredMethods()获取类的全部成员方法(只要存在就能拿到)Method getMethod(String name, Class<?> parameterTypes)获取类的某个成员方法(只能获取public修饰的)Method getDeclaredMethod(String name, Class<?> parameterTypes)获取类的某个成员方法(只要存在就能拿到)         获取成员方法的作用

                获取成员方法的作用是执行该方法

Method提供的方法说明public Object invoke(Object obj, Object... args)执行某个对象的该方法public void setAccessible(boolean flag)设置为ture,表示禁止检查访问控制 public class Dog { private String name; private int age; public static int o; public static final String C = "狗狗"; public Dog() { } public Dog(String name, int age) { this.name = name; this.age = age; } public String eat(String food) { return "吃" + food + "吃的贼多"; } public void run() { System.out.println("跑的贼快"); } private void sleep() { System.out.println("睡得贼香"); } } @Test public void testGetMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class d = Dog.class; //Method[] getMethods() 获取类的全部成员方法(只能获取public 修饰的) 使用较少 Method[] methods = d.getMethods(); for(Method m : methods){ System.out.println(m.getName() + "-->" + m.getParameterTypes().length); } System.out.println("-------------------"); //Method[] getDeclaredMethods() 获取类的全部成员方法(只要存在就能拿到) Method[] methods2 = d.getDeclaredMethods(); for(Method m : methods2){ System.out.println(m.getName() + "-->" + m.getParameterTypes().length); } System.out.println("-------------------"); //Method getMethod(String name, Class<?> parameterTypes) 获取类的某个成员方法(只能获取public修饰的) Method method = d.getMethod("eat", String.class); System.out.println(method.getName() + "-->" + method.getReturnType()); //Method getDeclaredMethod(String name, Class<?> parameterTypes) 获取类的某个成员方法(只要存在就能拿到) Method method2 = d.getDeclaredMethod("sleep"); System.out.println(method2.getName() + "-->" + method2.getReturnType()); System.out.println("===================="); //public Object invoke(Object obj, Object... args) 执行某个对象的该方法 Dog dog = new Dog(); //method为 public 可直接调用 String s = (String) method.invoke(dog, "王中王"); System.out.println(s); //method2->sleep为private 直接执行会报错 需要 void setAccessible(boolean flag) 设置为ture,表示禁止检查访问控制 //public void setAccessible(boolean flag) 设置为ture,表示禁止检查访问控制 method2.setAccessible(true); method2.invoke(dog); } 六. 反射的作用、应用场景         作用

                1. 基本作用:可以得到一个类的全部成分然后进行操作。

                2. 可以破坏封装性

                3. 最重要的用途:适合做Java框架,主流的框架都会基于反射设计出一些通用的功能

        简易版框架

                实现步骤:

                1. 定义一个方法,可以接收任意对象

                2. 没收到一个对象后,使用反射获取该对象的Class对象,然后获取全部的成员变量

                3. 变量成员变量,然后提取成员变量在该对象中的具体值

                4. 把成员变量名和值写到文件中

public class Student { private String name; private int age; private String gender; private String grade; public Student() { } public Student(String name, int age, String gender, String grade) { this.name = name; this.age = age; this.gender = gender; this.grade = grade; } } public class Teacher { private String name; private int age; private String subject; public Teacher() { } public Teacher(String name, int age, String subject) { this.name = name; this.age = age; this.subject = subject; } } @Test public void testA() throws Exception { Student s1 = new Student("卡莎", 18, "女", "99.8"); Teacher teacher = new Teacher("张飞", 25, "语文"); ObjectFrame.saveObject(s1); ObjectFrame.saveObject(teacher); }

标签:

Java反射由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Java反射