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

时间:2024-01-28 20:59:32

文档目录:

一、反射机制的作用

二、反射机制相关类

三、获取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