• java进阶(41)--反射机制


    文档目录:

    一、反射机制的作用

    二、反射机制相关类

    三、获取class的三种方式

    四、通过反射实例化对象

    五、通过读属性文件实例化对象

    六、通过反射机制访问对象属性

    七、通过反射机制调用方法

    ---------------------------------------分割线:正文--------------------------------------------------------

    一、反射机制的作用

    1、通过java语言中反射机制可以操作字节码文件

    2、通过反射机制可以操作代码片段(class文件)

     

    二、反射机制相关类

    1、对应的包:java.lang.reflect.*

    2、有哪些重要的类:

    java.lang.class --> 代表整个字节码文件,代码一个类型,代码整个类

    java.lang.reflect.Method --> 代表字节码中的方法字节码,代码类中构造方法

    java.lang.reflect.Constructor --> 代表字节码中构造方法字节码,代表类中构造方法

    java.lang.reflect.Field -->代表类中属性

     

    三、获取class的三种方式

    1、forName()

     1 package com.bk.java.Test41.reflect01;
     2 
     3 public class ReflectTest01 {
     4     public static void main(String[] args) throws ClassNotFoundException {
     5         Class c1=Class.forName("java.lang.String");
     6         Class c2=Class.forName("java.util.Date");
     7         Class c3=Class.forName("java.lang.Integer");
     8         System.out.println(c1);
     9         System.out.println(c2);
    10         System.out.println(c3);
    11     }
    12 }

    查看执行结果:

    class java.lang.String
    class java.util.Date
    class java.lang.Integer

     

    2、getClass()

     1 package com.bk.java.Test41.reflect01;
     2 
     3 public class ReflectTest02 {
     4     public static void main(String[] args) throws ClassNotFoundException {
     5         String s="abc";
     6         Class c1=Class.forName("java.lang.String");
     7         Class x=s.getClass();
     8         //内存地址一致,都指向方法区中的字节码
     9         System.out.println(x==c1);
    10     }
    11 }

    执行结果为true

     

    3、.class属性

     1 package com.bk.java.Test41.reflect01;
     2 
     3 public class ReflectTest03 {
     4     public static void main(String[] args) {
     5         String s="123";
     6         Class y=s.getClass();
     7         Class z=String.class;
     8         System.out.println(y==z);
     9     }
    10 }

    执行结果为true

     

    四、通过反射实例化对象

     1 package com.bk.java.Test41.reflect01;
     2 
     3 public class ReflectTest04 {
     4     public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
     5         Class c=Class.forName("com.bk.java.Test41.reflect01.User");
     6         //必须保证User类包含无参构造的方法,调用User类的无参构造方法,完成实例对象的创建
     7         Object obj= c.newInstance();
     8         System.out.println(obj);
     9     }
    10 }

    查看运行结果

    调用了User类的无参构造方法
    com.bk.java.Test41.reflect01.User@1b6d3586

     

    五、通过读属性文件实例化对象

    1、通过i/o流读取classinfo.properties

     配置文件:

    classinfo.properties:

    className=com.bk.java.Test41.reflect01.User
     1 package com.bk.java.Test41.reflect01;
     2 
     3 import java.io.FileNotFoundException;
     4 import java.io.FileReader;
     5 import java.io.IOException;
     6 import java.util.Properties;
     7 
     8 public class ReflectTest05 {
     9     public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
    10         //通过I/O流读取classinfo.properties文件
    11         FileReader reader=new FileReader("src/com/bk/java/Test41/reflect01/classinfo.properties");
    12         //创建属性类对象
    13         Properties pro=new Properties();
    14         pro.load(reader);
    15         //关闭流
    16         reader.close();
    17         //通过key获取value
    18         String className=pro.getProperty("className");
    19         System.out.println(className);
    20         //通过反射机制实例化对象
    21         Class c=Class.forName(className);
    22         Object obj=c.newInstance();
    23         System.out.println(obj);
    24     }
    25 }

    查看执行结果:

    com.bk.java.Test41.reflect01.User
    调用了User类的无参构造方法
    com.bk.java.Test41.reflect01.User@1b6d3586

    修改配置文件后再次调用查看结果

    className=java.util.Date
    java.util.Date
    Mon Apr 05 17:21:25 CST 2021

     

    2、以流的形式直接返回

     1 package com.bk.java.Test41.reflect01;
     2 
     3 import java.io.FileNotFoundException;
     4 import java.io.FileReader;
     5 import java.io.IOException;
     6 import java.util.Properties;
     7 
     8 public class ReflectTest06 {
     9     public static void main(String[] args) throws IOException {
    10         String path=Thread.currentThread().getContextClassLoader().getResource("com/bk/java/Test41/reflect01/classinfo.properties").getPath();
    11         FileReader reader=new FileReader(path);
    12         Properties pro=new Properties();
    13         pro.load(reader);
    14         reader.close();
    15         //通过key获取value
    16         String className=pro.getProperty("className");
    17         System.out.println(className);
    18     }
    19 }

    查看返回结果:返回结果同上

    java.util.Date

    改进代码如下:

    package com.bk.java.Test41.reflect01;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    public class ReflectTest07 {
        public static void main(String[] args) throws IOException {
            InputStream in=Thread.currentThread().getContextClassLoader().getResourceAsStream("com/bk/java/Test41/reflect01/classinfo.properties");
            Properties pro=new Properties();
            pro.load(in);
            in.close();
            //通过key获取value
            String className=pro.getProperty("className");
            System.out.println(className);
        }
    }

    3、使用资源绑定器:

    package com.bk.java.Test41.reflect01;
    
    import java.util.ResourceBundle;
    
    public class ResourceBundleTest {
        public static void main(String[] args) {
            ResourceBundle bundle=ResourceBundle.getBundle("com/bk/java/Test41/reflect01/classinfo");
            String className=bundle.getString("className");
            System.out.println(className);
        }
    }

    查看运行结果:

    java.util.Date

     

    六、通过反射机制访问对象属性

    创建一个Student类

     1 package com.bk.java.Test41.reflect02;
     2 
     3 public class Student {
     4     public int no;
     5     private String name;
     6     protected int age;
     7     boolean sex;
     8 
     9     public Student() {
    10     }
    11 
    12     public int getNo() {
    13         return no;
    14     }
    15 
    16     public void setNo(int no) {
    17         this.no = no;
    18     }
    19 
    20     public String getName() {
    21         return name;
    22     }
    23 
    24     public void setName(String name) {
    25         this.name = name;
    26     }
    27 
    28     public int getAge() {
    29         return age;
    30     }
    31 
    32     public void setAge(int age) {
    33         this.age = age;
    34     }
    35 
    36     public boolean isSex() {
    37         return sex;
    38     }
    39 
    40     public void setSex(boolean sex) {
    41         this.sex = sex;
    42     }
    43 }

    通过反射机制访问对象属性

     1 package com.bk.java.Test41.reflect02;
     2 
     3 import java.lang.reflect.Field;
     4 
     5 public class ReflectTest01 {
     6     public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
     7         Class studentClass=Class.forName("com.bk.java.Test41.reflect02.Student");
     8         Object obj=studentClass.newInstance();
     9         //获取no属性通过属性name
    10         Field noField=studentClass.getDeclaredField("no");
    11         //给obj对象的no属性赋值
    12         noField.set(obj,11111);
    13         //读取属性的值
    14         System.out.println(noField.get(obj));
    15     }
    16 }

    查看输出结果

    11111

     

    七、通过反射机制调用方法

    原始方法:

    package com.bk.java.Test41.reflect03;
    
    public class ReflectTest {
        public static void main(String[] args) {
            //原始方法调用UserSevice.login方法
            UserService userService=new UserService();
            boolean loginSuccess=userService.login("admin","123");
            System.out.println(loginSuccess?"登录成功":"登录失败");
        }
    }

    通过反射机制调用:

     1 package com.bk.java.Test41.reflect03;
     2 
     3 import java.lang.reflect.InvocationTargetException;
     4 import java.lang.reflect.Method;
     5 
     6 public class ReflectTest {
     7     public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
     8 //        //原始方法调用UserSevice.login方法
     9 //        UserService userService=new UserService();
    10 //        boolean loginSuccess=userService.login("admin","123");
    11 //        System.out.println(loginSuccess?"登录成功":"登录失败");
    12         Class userServiceClass =Class.forName("com.bk.java.Test41.reflect03.UserService");
    13         //创建实例对象
    14         Object obj=userServiceClass.newInstance();
    15         //获取Method
    16         Method loginMethod=userServiceClass.getDeclaredMethod("login", String.class, String.class);
    17         //调用方法
    18         Object retvalue=loginMethod.invoke(obj,"admin","123");
    19         System.out.println(retvalue);
    20     }
    21 }

    查看运行结果:

    true
  • 相关阅读:
    Linux下修改MySQL数据库字符编码为UTF-8解决中文乱码
    ODS与DW之间的关系
    如何使用Hive&R从Hadoop集群中提取数据进行分析
    CentOS6.5下实现R绘图
    Util.FSUtils: Waiting for dfs to exit safe mode
    Grafana邮件报警
    CentOS7安装Grafana(Yum)
    CentOS7安装Node_exporter(二进制)
    CentOS7安装Prometheus(二进制)
    linux查看进程内存占用
  • 原文地址:https://www.cnblogs.com/mrwhite2020/p/14618438.html
Copyright © 2020-2023  润新知