JAVA反射通俗易懂转 转载大牛的 通俗易懂

Xilinx Vivado vitis IDE launch Failed \ Web installer client Obsolete 怎么办 Xilinx vitis_IDE failed Web installer client Obsolete 阅读详情

https://blog.youkuaiyun.com/sinat_21843047/article/details/80066333

反射是框架设计的灵魂

(使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))

 

一、反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

 

 

以上的总结就是什么是反射

反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

     (其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)

如图是类的正常加载过程:反射的原理在与class对象。

熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。

 

 

其中这个Class对象很特殊。我们先了解一下这个Class类

 

二、查看Class类在java中的api详解(1.7的API)

如何阅读java中的api详见java基础之——String字符串处理

 

 

Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型)

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。

 

没有公共的构造方法,方法共有64个太多了。下面用到哪个就详解哪个吧

 

 

三、反射的使用(这里使用Student类做演示)

先写一个Student类。

 

1、获取Class对象的三种方式

1.1 Object ——> getClass();
1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
1.3 通过Class类的静态方法:forName(String  className)(常用)

 

其中1.1是因为Object类中的getClass方法、因为所有类都继承Object类。从而调用Object类来获取

 

 

[java] view plain copy

  1. <span style="font-size:18px;">package fanshe;  
  2. /** 
  3.  * 获取Class对象的三种方式 
  4.  * 1 Object ——> getClass(); 
  5.  * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性 
  6.  * 3 通过Class类的静态方法:forName(String  className)(常用) 
  7.  * 
  8.  */  
  9. public class Fanshe {  
  10.     public static void main(String[] args) {  
  11.         //第一种方式获取Class对象    
  12.         Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。  
  13.         Class stuClass = stu1.getClass();//获取Class对象  
  14.         System.out.println(stuClass.getName());  
  15.           
  16.         //第二种方式获取Class对象  
  17.         Class stuClass2 = Student.class;  
  18.         System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个  
  19.           
  20.         //第三种方式获取Class对象  
  21.         try {  
  22.             Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名  
  23.             System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象  
  24.         } catch (ClassNotFoundException e) {  
  25.             e.printStackTrace();  
  26.         }  
  27.           
  28.     }  
  29. }</span>  

注意:在运行期间,一个类,只有一个Class对象产生。

三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。

 

2、通过反射获取构造方法并使用:

student类:

[java] view plain copy

  1. package fanshe;  
  2.   
  3. public class Student {  
  4.       
  5.     //---------------构造方法-------------------  
  6.     //(默认的构造方法)  
  7.     Student(String str){  
  8.         System.out.println("(默认)的构造方法 s = " + str);  
  9.     }  
  10.       
  11.     //无参构造方法  
  12.     public Student(){  
  13.         System.out.println("调用了公有、无参构造方法执行了。。。");  
  14.     }  
  15.       
  16.     //有一个参数的构造方法  
  17.     public Student(char name){  
  18.         System.out.println("姓名:" + name);  
  19.     }  
  20.       
  21.     //有多个参数的构造方法  
  22.     public Student(String name ,int age){  
  23.         System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。  
  24.     }  
  25.       
  26.     //受保护的构造方法  
  27.     protected Student(boolean n){  
  28.         System.out.println("受保护的构造方法 n = " + n);  
  29.     }  
  30.       
  31.     //私有构造方法  
  32.     private Student(int age){  
  33.         System.out.println("私有的构造方法   年龄:"+ age);  
  34.     }  
  35.   
  36. }  


共有6个构造方法;

 

测试类:

[java] view plain copy

  1. package fanshe;  
  2.   
  3. import java.lang.reflect.Constructor;  
  4.   
  5.   
  6. /* 
  7.  * 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员; 
  8.  *  
  9.  * 1.获取构造方法: 
  10.  *      1).批量的方法: 
  11.  *          public Constructor[] getConstructors():所有"公有的"构造方法 
  12.             public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有) 
  13.       
  14.  *      2).获取单个的方法,并调用: 
  15.  *          public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法: 
  16.  *          public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有; 
  17.  *       
  18.  *          调用构造方法: 
  19.  *          Constructor-->newInstance(Object... initargs) 
  20.  */  
  21. public class Constructors {  
  22.   
  23.     public static void main(String[] args) throws Exception {  
  24.         //1.加载Class对象  
  25.         Class clazz = Class.forName("fanshe.Student");  
  26.           
  27.           
  28.         //2.获取所有公有构造方法  
  29.         System.out.println("**********************所有公有构造方法*********************************");  
  30.         Constructor[] conArray = clazz.getConstructors();  
  31.         for(Constructor c : conArray){  
  32.             System.out.println(c);  
  33.         }  
  34.           
  35.           
  36.         System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");  
  37.         conArray = clazz.getDeclaredConstructors();  
  38.         for(Constructor c : conArray){  
  39.             System.out.println(c);  
  40.         }  
  41.           
  42.         System.out.println("*****************获取公有、无参的构造方法*******************************");  
  43.         Constructor con = clazz.getConstructor(null);  
  44.         //1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型  
  45.         //2>、返回的是描述这个无参构造函数的类对象。  
  46.       
  47.         System.out.println("con = " + con);  
  48.         //调用构造方法  
  49.         Object obj = con.newInstance();  
  50.     //  System.out.println("obj = " + obj);  
  51.     //  Student stu = (Student)obj;  
  52.           
  53.         System.out.println("******************获取私有构造方法,并调用*******************************");  
  54.         con = clazz.getDeclaredConstructor(char.class);  
  55.         System.out.println(con);  
  56.         //调用构造方法  
  57.         con.setAccessible(true);//暴力访问(忽略掉访问修饰符)  
  58.         obj = con.newInstance('男');  
  59.     }  
  60.       
  61. }  

 

后台输出:

[java] view plain copy

  1. **********************所有公有构造方法*********************************  
  2. public fanshe.Student(java.lang.String,int)  
  3. public fanshe.Student(char)  
  4. public fanshe.Student()  
  5. ************所有的构造方法(包括:私有、受保护、默认、公有)***************  
  6. private fanshe.Student(int)  
  7. protected fanshe.Student(boolean)  
  8. public fanshe.Student(java.lang.String,int)  
  9. public fanshe.Student(char)  
  10. public fanshe.Student()  
  11. fanshe.Student(java.lang.String)  
  12. *****************获取公有、无参的构造方法*******************************  
  13. con = public fanshe.Student()  
  14. 调用了公有、无参构造方法执行了。。。  
  15. ******************获取私有构造方法,并调用*******************************  
  16. public fanshe.Student(char)  
  17. 姓名:男  

 

调用方法:

1.获取构造方法:

  1).批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
     
  2).获取单个的方法,并调用:
public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

  调用构造方法:

Constructor-->newInstance(Object... initargs)

 

2、newInstance是 Constructor类的方法(管理构造函数的类)

api的解释为:

newInstance(Object... initargs)
           使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

它的返回值是T类型,所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用

3、获取成员变量并调用

student类:

[java] view plain copy

  1. <span style="font-size:14px;">package fanshe.field;  
  2.   
  3. public class Student {  
  4.     public Student(){  
  5.           
  6.     }  
  7.     //**********字段*************//  
  8.     public String name;  
  9.     protected int age;  
  10.     char sex;  
  11.     private String phoneNum;  
  12.       
  13.     @Override  
  14.     public String toString() {  
  15.         return "Student [name=" + name + ", age=" + age + ", sex=" + sex  
  16.                 + ", phoneNum=" + phoneNum + "]";  
  17.     }  
  18.       
  19.       
  20. }</span>  

 

测试类:

[java] view plain copy

  1. <span style="font-size:14px;">package fanshe.field;  
  2. import java.lang.reflect.Field;  
  3. /* 
  4.  * 获取成员变量并调用: 
  5.  *  
  6.  * 1.批量的 
  7.  *      1).Field[] getFields():获取所有的"公有字段" 
  8.  *      2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有; 
  9.  * 2.获取单个的: 
  10.  *      1).public Field getField(String fieldName):获取某个"公有的"字段; 
  11.  *      2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的) 
  12.  *  
  13.  *   设置字段的值: 
  14.  *      Field --> public void set(Object obj,Object value): 
  15.  *                  参数说明: 
  16.  *                  1.obj:要设置的字段所在的对象; 
  17.  *                  2.value:要为字段设置的值; 
  18.  *  
  19.  */  
  20. public class Fields {  
  21.   
  22.         public static void main(String[] args) throws Exception {  
  23.             //1.获取Class对象  
  24.             Class stuClass = Class.forName("fanshe.field.Student");  
  25.             //2.获取字段  
  26.             System.out.println("************获取所有公有的字段********************");  
  27.             Field[] fieldArray = stuClass.getFields();  
  28.             for(Field f : fieldArray){  
  29.                 System.out.println(f);  
  30.             }  
  31.             System.out.println("************获取所有的字段(包括私有、受保护、默认的)********************");  
  32.             fieldArray = stuClass.getDeclaredFields();  
  33.             for(Field f : fieldArray){  
  34.                 System.out.println(f);  
  35.             }  
  36.             System.out.println("*************获取公有字段**并调用***********************************");  
  37.             Field f = stuClass.getField("name");  
  38.             System.out.println(f);  
  39.             //获取一个对象  
  40.             Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();  
  41.             //为字段设置值  
  42.             f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"  
  43.             //验证  
  44.             Student stu = (Student)obj;  
  45.             System.out.println("验证姓名:" + stu.name);  
  46.               
  47.               
  48.             System.out.println("**************获取私有字段****并调用********************************");  
  49.             f = stuClass.getDeclaredField("phoneNum");  
  50.             System.out.println(f);  
  51.             f.setAccessible(true);//暴力反射,解除私有限定  
  52.             f.set(obj, "18888889999");  
  53.             System.out.println("验证电话:" + stu);  
  54.               
  55.         }  
  56.     }</span><span style="font-size:18px;">  
  57. </span>  


后台输出:

 

[java] view plain copy

  1. ************获取所有公有的字段********************  
  2. public java.lang.String fanshe.field.Student.name  
  3. ************获取所有的字段(包括私有、受保护、默认的)********************  
  4. public java.lang.String fanshe.field.Student.name  
  5. protected int fanshe.field.Student.age  
  6. char fanshe.field.Student.sex  
  7. private java.lang.String fanshe.field.Student.phoneNum  
  8. *************获取公有字段**并调用***********************************  
  9. public java.lang.String fanshe.field.Student.name  
  10. 验证姓名:刘德华  
  11. **************获取私有字段****并调用********************************  
  12. private java.lang.String fanshe.field.Student.phoneNum  
  13. 验证电话:Student [name=刘德华, age=0, sex=  


由此可见

调用字段时:需要传递两个参数:

Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
//为字段设置值
f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"

第一个参数:要传入设置的对象,第二个参数:要传入实参

4、获取成员方法并调用

student类:

[java] view plain copy

  1. <span style="font-size:14px;">package fanshe.method;  
  2.   
  3. public class Student {  
  4.     //**************成员方法***************//  
  5.     public void show1(String s){  
  6.         System.out.println("调用了:公有的,String参数的show1(): s = " + s);  
  7.     }  
  8.     protected void show2(){  
  9.         System.out.println("调用了:受保护的,无参的show2()");  
  10.     }  
  11.     void show3(){  
  12.         System.out.println("调用了:默认的,无参的show3()");  
  13.     }  
  14.     private String show4(int age){  
  15.         System.out.println("调用了,私有的,并且有返回值的,int参数的show4(): age = " + age);  
  16.         return "abcd";  
  17.     }  
  18. }  
  19. </span>  


测试类:

[java] view plain copy

  1. <span style="font-size:14px;">package fanshe.method;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. /* 
  6.  * 获取成员方法并调用: 
  7.  *  
  8.  * 1.批量的: 
  9.  *      public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类) 
  10.  *      public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的) 
  11.  * 2.获取单个的: 
  12.  *      public Method getMethod(String name,Class<?>... parameterTypes): 
  13.  *                  参数: 
  14.  *                      name : 方法名; 
  15.  *                      Class ... : 形参的Class类型对象 
  16.  *      public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 
  17.  *  
  18.  *   调用方法: 
  19.  *      Method --> public Object invoke(Object obj,Object... args): 
  20.  *                  参数说明: 
  21.  *                  obj : 要调用方法的对象; 
  22.  *                  args:调用方式时所传递的实参; 
  23.  
  24. ): 
  25.  */  
  26. public class MethodClass {  
  27.   
  28.     public static void main(String[] args) throws Exception {  
  29.         //1.获取Class对象  
  30.         Class stuClass = Class.forName("fanshe.method.Student");  
  31.         //2.获取所有公有方法  
  32.         System.out.println("***************获取所有的”公有“方法*******************");  
  33.         stuClass.getMethods();  
  34.         Method[] methodArray = stuClass.getMethods();  
  35.         for(Method m : methodArray){  
  36.             System.out.println(m);  
  37.         }  
  38.         System.out.println("***************获取所有的方法,包括私有的*******************");  
  39.         methodArray = stuClass.getDeclaredMethods();  
  40.         for(Method m : methodArray){  
  41.             System.out.println(m);  
  42.         }  
  43.         System.out.println("***************获取公有的show1()方法*******************");  
  44.         Method m = stuClass.getMethod("show1", String.class);  
  45.         System.out.println(m);  
  46.         //实例化一个Student对象  
  47.         Object obj = stuClass.getConstructor().newInstance();  
  48.         m.invoke(obj, "刘德华");  
  49.           
  50.         System.out.println("***************获取私有的show4()方法******************");  
  51.         m = stuClass.getDeclaredMethod("show4", int.class);  
  52.         System.out.println(m);  
  53.         m.setAccessible(true);//解除私有限定  
  54.         Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参  
  55.         System.out.println("返回值:" + result);  
  56.           
  57.           
  58.     }  
  59. }  
  60. </span>  

控制台输出:

[java] view plain copy

  1. ***************获取所有的”公有“方法*******************  
  2. public void fanshe.method.Student.show1(java.lang.String)  
  3. public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException  
  4. public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException  
  5. public final void java.lang.Object.wait() throws java.lang.InterruptedException  
  6. public boolean java.lang.Object.equals(java.lang.Object)  
  7. public java.lang.String java.lang.Object.toString()  
  8. public native int java.lang.Object.hashCode()  
  9. public final native java.lang.Class java.lang.Object.getClass()  
  10. public final native void java.lang.Object.notify()  
  11. public final native void java.lang.Object.notifyAll()  
  12. ***************获取所有的方法,包括私有的*******************  
  13. public void fanshe.method.Student.show1(java.lang.String)  
  14. private java.lang.String fanshe.method.Student.show4(int)  
  15. protected void fanshe.method.Student.show2()  
  16. void fanshe.method.Student.show3()  
  17. ***************获取公有的show1()方法*******************  
  18. public void fanshe.method.Student.show1(java.lang.String)  
  19. 调用了:公有的,String参数的show1(): s = 刘德华  
  20. ***************获取私有的show4()方法******************  
  21. private java.lang.String fanshe.method.Student.show4(int)  
  22. 调用了,私有的,并且有返回值的,int参数的show4(): age = 20  
  23. 返回值:abcd  


由此可见:

m = stuClass.getDeclaredMethod("show4", int.class);//调用制定方法(所有包括私有的),需要传入两个参数,第一个是调用的方法名称,第二个是方法的形参类型,切记是类型。
System.out.println(m);
m.setAccessible(true);//解除私有限定
Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参
System.out.println("返回值:" + result);//

 

控制台输出:

[java] view plain copy

  1. ***************获取所有的”公有“方法*******************  
  2. public void fanshe.method.Student.show1(java.lang.String)  
  3. public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException  
  4. public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException  
  5. public final void java.lang.Object.wait() throws java.lang.InterruptedException  
  6. public boolean java.lang.Object.equals(java.lang.Object)  
  7. public java.lang.String java.lang.Object.toString()  
  8. public native int java.lang.Object.hashCode()  
  9. public final native java.lang.Class java.lang.Object.getClass()  
  10. public final native void java.lang.Object.notify()  
  11. public final native void java.lang.Object.notifyAll()  
  12. ***************获取所有的方法,包括私有的*******************  
  13. public void fanshe.method.Student.show1(java.lang.String)  
  14. private java.lang.String fanshe.method.Student.show4(int)  
  15. protected void fanshe.method.Student.show2()  
  16. void fanshe.method.Student.show3()  
  17. ***************获取公有的show1()方法*******************  
  18. public void fanshe.method.Student.show1(java.lang.String)  
  19. 调用了:公有的,String参数的show1(): s = 刘德华  
  20. ***************获取私有的show4()方法******************  
  21. private java.lang.String fanshe.method.Student.show4(int)  
  22. 调用了,私有的,并且有返回值的,int参数的show4(): age = 20  
  23. 返回值:abcd  


其实这里的成员方法:在模型中有属性一词,就是那些setter()方法和getter()方法。还有字段组成,这些内容在内省中详解

5、反射main方法

student类:

[java] view plain copy

  1. <span style="font-size:14px;">package fanshe.main;  
  2.   
  3. public class Student {  
  4.   
  5.     public static void main(String[] args) {  
  6.         System.out.println("main方法执行了。。。");  
  7.     }  
  8. }  
  9. </span>  

 

测试类:

[java] view plain copy

  1. <span style="font-size:14px;">package fanshe.main;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. /** 
  6.  * 获取Student类的main方法、不要与当前的main方法搞混了 
  7.  */  
  8. public class Main {  
  9.       
  10.     public static void main(String[] args) {  
  11.         try {  
  12.             //1、获取Student对象的字节码  
  13.             Class clazz = Class.forName("fanshe.main.Student");  
  14.               
  15.             //2、获取main方法  
  16.              Method methodMain = clazz.getMethod("main", String[].class);//第一个参数:方法名称,第二个参数:方法形参的类型,  
  17.             //3、调用main方法  
  18.             // methodMain.invoke(null, new String[]{"a","b","c"});  
  19.              //第一个参数,对象类型,因为方法是static静态的,所以为null可以,第二个参数是String数组,这里要注意在jdk1.4时是数组,jdk1.5之后是可变参数  
  20.              //这里拆的时候将  new String[]{"a","b","c"} 拆成3个对象。。。所以需要将它强转。  
  21.              methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一  
  22.             // methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二  
  23.               
  24.         } catch (Exception e) {  
  25.             e.printStackTrace();  
  26.         }  
  27.           
  28.           
  29.     }  
  30. }</span><span style="font-size:18px;">  
  31. </span>  


控制台输出:

main方法执行了。。。

6、反射方法的其它使用之---通过反射运行配置文件内容

student类:

[java] view plain copy

  1. public class Student {  
  2.     public void show(){  
  3.         System.out.println("is show()");  
  4.     }  
  5. }  

 

配置文件以txt文件为例子(pro.txt):

[java] view plain copy

  1. className = cn.fanshe.Student  
  2. methodName = show  


测试类:

[java] view plain copy

  1. import java.io.FileNotFoundException;  
  2. import java.io.FileReader;  
  3. import java.io.IOException;  
  4. import java.lang.reflect.Method;  
  5. import java.util.Properties;  
  6.   
  7. /* 
  8.  * 我们利用反射和配置文件,可以使:应用程序更新时,对源码无需进行任何修改 
  9.  * 我们只需要将新类发送给客户端,并修改配置文件即可 
  10.  */  
  11. public class Demo {  
  12.     public static void main(String[] args) throws Exception {  
  13.         //通过反射获取Class对象  
  14.         Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student"  
  15.         //2获取show()方法  
  16.         Method m = stuClass.getMethod(getValue("methodName"));//show  
  17.         //3.调用show()方法  
  18.         m.invoke(stuClass.getConstructor().newInstance());  
  19.           
  20.     }  
  21.       
  22.     //此方法接收一个key,在配置文件中获取相应的value  
  23.     public static String getValue(String key) throws IOException{  
  24.         Properties pro = new Properties();//获取配置文件的对象  
  25.         FileReader in = new FileReader("pro.txt");//获取输入流  
  26.         pro.load(in);//将流加载到配置文件对象中  
  27.         in.close();  
  28.         return pro.getProperty(key);//返回根据key获取的value值  
  29.     }  
  30. }  

 

控制台输出:

is show()

 

需求:
当我们升级这个系统时,不要Student类,而需要新写一个Student2的类时,这时只需要更改pro.txt的文件内容就可以了。代码就一点不用改动

 

要替换的student2类:

[java] view plain copy

  1. public class Student2 {  
  2.     public void show2(){  
  3.         System.out.println("is show2()");  
  4.     }  
  5. }  

 

配置文件更改为:

[java] view plain copy

  1. className = cn.fanshe.Student2  
  2. methodName = show2  

控制台输出:

is show2();

7、反射方法的其它使用之---通过反射越过泛型检查

泛型用在编译期,编译过后泛型擦除(消失掉)。所以是可以通过反射越过泛型检查的

测试类:

[java] view plain copy

  1. import java.lang.reflect.Method;  
  2. import java.util.ArrayList;  
  3.   
  4. /* 
  5.  * 通过反射越过泛型检查 
  6.  *  
  7.  * 例如:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值? 
  8.  */  
  9. public class Demo {  
  10.     public static void main(String[] args) throws Exception{  
  11.         ArrayList<String> strList = new ArrayList<>();  
  12.         strList.add("aaa");  
  13.         strList.add("bbb");  
  14.           
  15.     //  strList.add(100);  
  16.         //获取ArrayList的Class对象,反向的调用add()方法,添加数据  
  17.         Class listClass = strList.getClass(); //得到 strList 对象的字节码 对象  
  18.         //获取add()方法  
  19.         Method m = listClass.getMethod("add", Object.class);  
  20.         //调用add()方法  
  21.         m.invoke(strList, 100);  
  22.           
  23.         //遍历集合  
  24.         for(Object obj : strList){  
  25.             System.out.println(obj);  
  26.         }  
  27.     }  
  28. }  


控制台输出:

aaa
bbb
100

下面文章提供了classloader的机制来加载类产生类对象

https://blog.youkuaiyun.com/the_fire/article/details/6020402?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-3.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-3.control

YOLOv11的扩散模型去噪预处理-(在推理前对低质量图像进行增强) 摘要: 扩散模型与YOLOv11的结合有效提升了复杂场景下的目标检测性能。针对低质量图像(如噪声、低光照)导致YOLOv11特征提取退化的问题,研究提出了一种基于条件扩散模型的预处理方法。通过语义引导的渐进式去噪,在保留关键检测特征的同时,显著改善了图像质量。技术核心包括:1)利用YOLOv11浅层特征作为条件输入;2)交叉注意力机制实现任务感知去噪;3)知识蒸馏与潜空间扩散加速推理。实验表明,该方法使mAP50提升19%,在15步内达到传统百步去噪效果,平衡了精度与实时性需求,为鲁棒性目标检测提供了新思路 阅读详情

相关推荐

银河麒麟V10系统下,手把手解决Ollama安装报错‘GLIBCXX_3.4.25 not found’

本文详细介绍了在银河麒麟V10系统下解决Ollama安装报错‘GLIBCXX_3.4.25 not found’的实战指南。通过隔离编译新版libstdc++、环境变量引导和服务化封装等安全方案,确保在不破坏系统稳定性的前提下顺利运行Ollama,适用于国产操作系统与AI工具的兼容性需求。

weixin_42556197的博客 484

Java反射使用示例

上述代码中,我们首先获取 MyClass 的 Class 对象,然后使用 newInstance() 方法创建 MyClass 的一个实例,接着使用 getDeclaredMethod() 方法获取 myPrivateMethod 方法的 Method 对象,由于 myPrivateMethod 是私有方法,因此我们需要调用 setAccessible(true) 方法来允许访问私有方法,最后使用 invoke() 方法调用该方法。下面我们就来看几个动态调用方法的例子。这就是几个动态调用方法的例子。

qq_23921815的博客 1978

使用GDScript(godot)生成仿杀戮尖塔地图

使用GDScript(godot)生成仿杀戮尖塔地图 extends Node2D export (PackedScene) var Ball var 被连接数 = {} # 每个怪物被下层怪物连接的数量 最多为2 var 连接1 = {} # 第一次连接的上层怪物位置 var 连接2 = {} # 第二次连接的上层怪物位置 var 怪物数量 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0] # 每层怪物的数量 var 总层数 =8 # 总层数 var 怪物坐标行 = {} #

weixin_45038716的博客 3010

Java反射怎么调用静态(私有)方法和非静态(私有)方法

在一个类中声明一个静态方法、非静态方法、私有静态方法和私有非静态方法。 public class StaticAndNoStaticTest { public static void staticMethod(String[] args) { for (String str : args) { System.out.println(str); } } ...

riemann_的博客 1万+

Oracle监听配置

Oracle监听配置## 标题 选择“监听程序配置”,然后下一步。 选择重新配置,然后下一步/。 不用管,按下一步。 下一步。 选择“否”,下一步。 选择"本地net服务名配置",然后下一步。 选择“重新配置”,然后下一步。 服务名 是"Oracle",然后下一步。 主机为你的IP地址,在doc系统下通过"ipconfig"获取IP地址。然后输入,然后下一步。 选择“是,进行测试...

m0_46079215的博客 806

七星棋牌顶级运营产品全开源修复版源码教程:6端支持,200+子游戏玩法,完整搭建指南(含代码解析)

让您从源码下载到本地运行一步到位!此外,文中还将附带详细代码解析与操作步骤,即便没有开发经验,也能轻松完成二开与定制。数据库是棋牌游戏中极为关键的组成部分,用于存储用户信息、乐豆余额、游戏记录、提现申请等数据。以下是部分核心数据表结构示例,便于存储用户信息与游戏记录。AI模块能够控制游戏中的胜率,常用于调节玩家体验。防沉迷功能旨在限制未成年人游戏时间。的完整搭建流程,特别适合。首先,获取七星棋牌源码。本教程将为您详细讲解。

aa2031171的博客 7778

【Java】通过反射调用静态方法

想要通过反射获取单例模式类的对象。但是单例模式下,构造方法是私有的直接使用newInstance()会报错。如下代码 String name = "com.zifeiyu.Factory"; Factory fac = (Factory)Class.forName(name).newInstance(); 想着使用单例类提供的getInstance方法 String name = "com.zifeiyu.Factory"; Factory fac = (Factory)Class.forName(nam

Passer_hua的博客 3343

利用OTSU阈值算法在ZYNQ上实现浒苔识别

利用OTSU阈值算法进行图像二值化,结果用HDMI显示

qq_38075564的博客 1275

Java:通过反射调用静态方法、非静态方法

Java:通过反射调用静态方法、非静态方法

听海边涛声 1726

IC版图设计布局经验90条!

13 如果一个cell调用其它cell,被调用的cell的vssx,vddx,vssb,vddb如果没有和外层cell连起来,要打上PIN,否则通不过diva检查.尽量在布局低层cell时就连起来。48 在匹配电路的mos管左右画上dummy,用poly,poly的尺寸与管子尺寸一样,dummy与相邻的第一个poly gate的间距等于poly gate之间的间距。8 更改cell时查看路径,一定要在正确的library下更改,以防copy过来的cell是在其他的library下,被改错。

weixin_44606964的博客 910

MuJoCo与Isaac Sim的无缝对接:利用USD导出功能实现强化学习场景的跨平台迁移

本文详细介绍了如何通过USD导出功能实现MuJoCo与Isaac Sim的无缝对接,助力强化学习场景的跨平台迁移。文章解析了USD格式的核心优势,包括分层合成、物理属性继承和时间轴动画,并提供了从MJCF到USD的完整转换流程及在Isaac Sim中的高级应用技巧,帮助开发者高效迁移和优化强化学习环境。

weixin_29073241的博客 517

反射是框架设计的灵魂

声明非原创,原创文章链接https://blog.youkuaiyun.com/sinat_38259539/article/details/71799078 反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一、反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 要想解.

duanhwonline的专栏 193

【忍者算法】从拼积木到最长连续序列:一道别出心裁的数组题目|LeetCode 128 最长连续序列

本题核心:通过预处理数据结构来优化查找!

忍者算法的博客 738

反射 字段_阿里技术大牛;详解Java反射操作

享学课堂特邀作者:逐梦々少年转载请声明出处!前言在java开发过程中,经常使用一些框架如Spring、SpringMvc来简化开发操作,在web开发中,我们可以利用SpringMvc快速的把请求参数和实体进行转换,在使用数据库操作的时候,可以使用Mybatis/hibernate等框架实现实体与db的转换操作,这其中就是利用了java的反射机制实现的操作,所以java进阶之旅一定会有反射一席之地,...

weixin_27653327的博客 123

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

java 获取当前年_阿里技术大牛;详解Java反射操作

享学课堂特邀作者:逐梦々少年转载请声明出处!前言在java开发过程中,经常使用一些框架如Spring、SpringMvc来简化开发操作,在web开发中,我们可以利用SpringMvc快速的把请求参数和实体进行转换,在使用数据库操作的时候,可以使用Mybatis/hibernate等框架实现实体与db的转换操作,这其中就是利用了java的反射机制实现的操作,所以java进阶之旅一定会有反射一席之地,...

weixin_39773817的博客 80

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Java架构师必会几大技术点,转载大牛心得

Java架构必会几大技术点   关于学习架构,必须会的几点技术 1. java反射技术 2. xml文件处理 3. properties属性文件处理 4. 线程安全机制 5. annocation注解 6. 设计模式 7. 代理机制(aop) 8. serlvet基础(过滤器等等)几样比较实用的技术: 1. 模板语言freemarker 2. ognl 3. gson json工具类    ...

u011098604的博客 133

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Java反射学习总结

我开始学习反射的初衷是为了理解Spring 里的控制反转,其次可以利用反射来达到类中的解耦。 自己写的一些心得,希望能帮到大家 1.反射指的是对象的反向处理操作,是根据对象来取得对象的来源信息。 反射的核心是:将类编译的字节码映射成对应的Java类型 首先要理解,任何一个类的对象都可以通过Object类中的getClass()方法取得Class类对象 那么如何获取字节码呢? 第一 使...

weixin_34404393的博客 86

推荐人手一份!IT大牛总结这份python、Java学习清单转载达千万

Java和Python两门语言都是目前非常热门的语言,可谓北乔峰南慕容,二者不分上下,棋逢对手。但是对于初学者来说,非常困惑,不知道该从何下手,其实并不难 Java和Python双方都有各自适合和发展的领域,所以别人常问我学习什么语言好,或者让我在两种语言进行比较好坏,编程语言只有适不适合,不存在好坏,你想从事什么工作就去学习什么语言。 当然在2019年的今天,无论是java还是...

Python学习教程 252

Java注解学习复习总结-2021-06-14(连接转载)

最近在看关于Java Class类、反射、 注解的知识点,看来书、博文 ,一头雾水,也有可能是我这个初学者太水了; 还好遇到大牛的文章,写的非常好,由浅入深,条理清晰,推荐给大家: 关于注解:https://blog.youkuaiyun.com/shengzhu1/article/details/81271409 关于Class类与反射:https://blog.youkuaiyun.com/acm_lkl/article/details/78936124 先看Class类与反射,再看注解。 ...

lijian2020的博客 1211

Golang反射机制的一些规则

http://blog.golang.org/laws-of-reflection

kai_ding的专栏 1743

IOC和DI[转载]

学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring框架的IOC的理解以及谈谈我对Spring Ioc的理解。 一、分享Iteye的开涛对Ioc的精彩讲解   首先要分享的是Iteye的开涛这位技术牛人对Sprin...

田地里的大麦子 245

学Java不知从何下手?看这份详细的Java学习路线

最近有些网友问我如何学习学Java开发,还有些是想从别的方向想转过来。但都不太了解Java究竟需要学什么,究竟要从哪里学起,哪些是主流的Java后端技术等等,导致想学,但又很迷茫,不知从何下手。 Java是一门纯粹的面向对象的编程语言,所以除了基础语法之外,必须得弄懂它的oop 特性:封装、继承、多态。此外还有泛型、反射的特性,很多框架的技术都依赖它,比如Spring核心的Ioc和AO...

weixin_30273931的博客 190

利用抽象、多态实现无反射的绿色环保ORM框架

最近一直在忙新公司的基础库建设,对系统架构、开发框架及快速开发平台的设计实施都积累了一定的实践经验。 一般的中小型的软件开发公司,如果按照技术储备来衡量软件项目的技术含量的评定依据是可行的。但如果光是按照人头来衡量软件的技术含量是不可靠的。所以我们在选择跳巢的时候是选择大公司还是选择有技术含量的公司要根据自己的职业规划来。(本人最近体会到的一点跳巢经验分享给大家) 由于我现有单位技术部门刚刚成

王清培的个人博客 2509

依赖注入和控制反转的理解(转载)

学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring框架的IOC的理解以及谈谈我对Spring Ioc的理解。 一、分享Iteye的开涛对Ioc的精彩讲解   首先要分享的是Iteye的开涛这位技术牛人对Spr...

笔记 199

假如时光倒流,我会这么学习Java (转载)

回头看看, 我进入Java 领域已经快15个年头了, 虽然学的也一般, 但是分享下我的心得,估计也能帮大家少走点弯路。 入门 我在2001年之前是C/C++阵营, 有C和面向对象的基础, 后来转到Java ,发现没有指针的Java真是好简单, 另外Java 的类库好用的让人哭啊。后来我就看《Thinking in Java》 ,《 Java 核心技术 》, 感觉也不吃力。 ...

banjiangtian6973的博客 234

【转载】Java编程思想重点笔记(Java开发必看)

Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理解题(比如is-a关系和has-a关系的区别),也有深入的涉及RTTI和JVM底层反编译知识。   1. Java中的多态性理解(注意与C++区分) Java中除了static方法和...

Kai_Ge的博客 187
上一篇: RPC实现MQ通信的一个小例子
下一篇: java反射的理解
火星种萝卜
博客等级 码龄19年 438粉丝 304原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值