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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM