zoukankan      html  css  js  c++  java
  • java se基础高级之反射

    反射的概念

    Java 反射机制在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种 动态的获取信息 以及 动态调用对象的方法 的功能称为 java 的反射机制。
    反射机制很重要的一点就是“运行时”,其使得我们可以在程序运行时加载、探索以及使用编译期间完全未知的 .class 文件。
    换句话说,Java 程序可以加载一个运行时才得知名称的 .class 文件,然后获悉其完整构造,并生成其对象实体、或对其 fields(变量)设值、或调用其 methods(方法

    反射的好处: 通过反射技术可以获取到字节码文件对象,使用这个字节码文件对象就可以获取到一个类的所有信息,包括私有【构造方法对象,成员变量对象,成员方法对象,访问权限修饰符对象...】。
    之前的做法:
    Student s = new Student();
    学习反射之后的做法: 可以不需要显示地出现学生类就能够创建学生类的对象,并且可以动态创建对象,动态赋值,动态调用方法

    反射能够获取的相关对象

    • Class 类对象
    • Constructor 构造方法对象
    • Method 成员方法对象
    • Field 成员变量对象
    • Modifier 访问权限修饰符对象
    • Array 数组对象

     创建反射字节码文件对象的三种方式

    1.Class clazz = Class.forName("com.ashin.bean.Book");
    该方法要注意的是会抛出一个ClassNotFoundException因为输入的字符串代表的类可能不存在。推荐这种方法

    2.使用对象的getClass()来反向获取
    Book book = new Book();
    Class clazz = book.getClass();
    必须得先生成对象

    3.类字面常量
    Class clazz = Book.class;
    必须导入该类所在的包

    通过反射获取构造方法对象

    • Constructor<?>[] getConstructors() 获取到所有公有修饰的构造方法对象数组
    • Constructor<?>[] getDeclaredConstructors() 获取所有构造方法对象数组,包括私有
    • Constructor<T> getConstructor(Class<?>... parameterTypes) 获取单个公有修饰构造方法对象
    • Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取所有单个修饰的构造方法对象,包括私有

    例子

     1 public class ReflectDemo01 {
     2 public static void main(String[] args) throws ClassNotFoundException, FileNotFoundException, IOException {
     3 Student s1 = new Student("张三", 18, "北京西路", 1.80);
     4 Student s2 = new Student("张三", 18, "北京西路", 1.80);
     5 Class<? extends Student> c1 = s1.getClass();
     6 Class<? extends Student> c2 = s2.getClass();
     7 
     8 System.out.println(s1 == s2);
     9 System.out.println(c1 == c2);
    10 
    11 //    Class<Integer> c3 = int.class;
    12 Class<Student> c3 = Student.class;
    13 System.out.println(c1 == c3);
    14 
    15 Properties properties = new Properties();
    16 properties.load(new FileReader("config/classinfo.properties"));
    17 String classPath = properties.getProperty("className");
    18 Class<?> c4 = Class.forName(classPath);
    19 System.out.println(c1 == c4);
    20 
    21 }
    22 }

    通过反射获取成员变量对象

    • Field[] getFields() 获取所有公有的成员变量对象,包括父类的公有成员
    • Field[] getDeclaredFields() 获取所有本类的成员,包括私有
    • Field getDeclaredField(String name) 获取公有的成员属性,包括父类
    • Field getField(String name) 获取所有本类属性,包括私有
     1 public class ReflectDemo01 {
     2 public static void main(String[] args) throws Exception {
     3 Class<?> c = Class.forName("com.sxt.reflectdemo03.Student");
     4 // 通过字节码文件对象获取成员变量对象
     5 Field[] fields = c.getFields();
     6 for (Field field : fields) {
     7 System.out.println(field);
     8 }
     9 
    10 System.out.println("===============");
    11 Field[] declaredFields = c.getDeclaredFields();
    12 for (Field field : declaredFields) {
    13 System.out.println(field);
    14 }
    15 
    16 System.out.println("===============");
    17 Field nameField = c.getField("name");
    18 System.out.println(nameField);
    19 
    20 //    Field heightField = c.getField("height");
    21 //    System.out.println(heightField);
    22 
    23 Field heightField = c.getDeclaredField("height");
    24 System.out.println(heightField);
    25 }
    26 }

    通过反射获取成员方法对象,并且调用

    原来方式:

    Student s = new Student();
    s.method();

    • Method[] getMethods() 获取所有公有修饰的成员方法对象,包括父类公有方法
    • Method[] getDeclaredMethods() 获取本类所有成员方法对象,包括私有方法
    • Method getMethod(String name, Class<?>... parameterTypes)
    • Method getDeclaredMethod(String name, Class<?>... parameterTypes)
     1 public class ReflectDemo01 {
     2 public static void main(String[] args) throws Exception {
     3 Class<?> c = Class.forName("com.sxt.reflectdemo04.Student");
     4 Object instance = c.getConstructor().newInstance();
     5 
     6 // 通过字节码文件对象获取成员方法对象
     7 Method[] methods = c.getMethods();
     8 for (Method method : methods) {
     9 System.out.println(method);
    10 }
    11 
    12 System.out.println("=================");
    13 Method[] declaredMethods = c.getDeclaredMethods();
    14 for (Method method : declaredMethods) {
    15 System.out.println(method);
    16 }
    17 
    18 System.out.println("==================");
    19 // 获取method方法
    20 // Method getMethod(String name, Class<?>... parameterTypes)
    21 Method method = c.getMethod("method");
    22 System.out.println(method);
    23 
    24 Object invoke = method.invoke(instance);
    25 System.out.println(invoke);
    26 System.out.println("==================");
    27 // 获取setName方法并且赋值
    28 Method setNameMethod = c.getMethod("setName", String.class);
    29 setNameMethod.invoke(instance, "隔壁老周");
    30 
    31 // 获取getName方法
    32 Method getNameMethod = c.getMethod("getName");
    33 Object result = getNameMethod.invoke(instance);
    34 System.out.println(result);
    35 
    36 // 获取add方法并且调用
    37 Method addMethod = c.getMethod("add", int.class, int.class);
    38 Object result3 = addMethod.invoke(instance, 10, 20);
    39 System.out.println(result3);
    40 
    41 // 获取私有方法并且调用
    42 Method showMethod = c.getDeclaredMethod("show");
    43 showMethod.setAccessible(true);
    44 showMethod.invoke(instance);
    45 }
    46 }


    通过反射获取数组Array对象并且赋值

     1 public class ReflectDemo01 {
     2 public static void main(String[] args) throws Exception {
     3 Class<?> c = Class.forName("com.sxt.reflectdemo05.Demo");
     4 
     5 Object instance = c.getConstructor().newInstance();
     6 
     7 Field arrField = c.getDeclaredField("arr");
     8 
     9 Object arr = arrField.get(instance);
    10 
    11 //    if (arr instanceof int[]) {
    12 //    int[] array = (int[]) arr;
    13 //    System.out.println(Arrays.toString(array));
    14 //    }
    15 //    int i = Array.getInt(arr, 0);
    16 //    System.out.println(i);
    17 //    Object obj = Array.get(arr, 0);
    18 //    System.out.println(obj);
    19 //    System.out.println(Array.get(arr, 1));
    20 //    System.out.println(Array.get(arr, 2));
    21 ////    System.out.println(Array.get(arr, 3));
    22 //    int length = Array.getLength(arr);
    23 //    System.out.println(length);
    24 
    25 for (int i = 0; i < Array.getLength(arr); i++) {
    26 System.out.println(Array.get(arr, i));
    27 }
    28 
    29 Array.set(arr, 2, 100);
    30 System.out.println(Array.get(arr, 2));
    31 
    32 // 通过反射创建数组
    33 Object arrObj = Array.newInstance(String.class, 5);
    34 for (int i = 0; i < Array.getLength(arrObj); i++) {
    35 System.out.println(Array.get(arrObj, i));
    36 }
    37 
    38 Object arrobj2 = Array.newInstance(int.class, 2, 3);
    39 //    Object oneDimensson1 = Array.newInstance(int.class, 1);
    40 //    Object oneDimensson2 = Array.newInstance(int.class, 2);
    41 //    
    42 //    Array.set(arrobj2, 0, oneDimensson1);
    43 //    Array.set(arrobj2, 1, oneDimensson2);
    44 
    45 if (arrobj2 instanceof int[][]) {
    46 int[][] array = (int[][]) arrobj2;
    47 System.out.println(array);
    48 }
    49 }
    50 }
    51 
    52 class Demo {
    53 
    54 int[] arr = new int[3];
    55 
    56 public Demo() {
    57 arr[0] = 10;
    58 arr[1] = 20;
    59 }

    }

  • 相关阅读:
    bootstrap-treeview中文API 以及后台JSON数据处理
    @RequestMapping与@ModelAttribute 套路
    shiro文档
    自定义页面方法:${fns:sayHelloToName('zxw')}
    如何正确设置博客园的个人博客访问量-百度统计
    如何给博客园的博客添加时钟
    如何给自己的博客园的博客增加打赏设置
    python-turtle-画雪花-2种方法及效果的详解
    CUP监测1分钟(60s)的python的matplotlib动态作图
    tkinter+pickle+python的一个登录界面设计
  • 原文地址:https://www.cnblogs.com/lqhhome/p/10831875.html
Copyright © 2011-2022 走看看