厚积薄发系列之Java反射

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了厚积薄发系列之Java反射相关的知识,希望对你有一定的参考价值。

 

小生不才,在对于java反射仅仅停留在简单实用的基础上,下面我们来结合简单案例来了解一下java的反射

1.准备测试   准备两个类 和带有main方法的测试类

  • Test1类
    package reflection;
    
    public class Test1 {
        
        public void test() {
            System.out.println("Test1的方法");
        }
    
    }

     

  • Test2类
    package reflection;
    
    public class Test2 {
        
        public void test() {
            System.out.println("Test2的方法");
        }
    }

     

  • 带有main方法的测试类
    package reflection;
    
    public class Main {
    
        public static void main(String[] args) {
            new Test1().test();
        }
    
    }

     

2.需求提出  现在main方法中运行的时候是运行Test1测试类的test()方法  如果我们有需求替换成Test2类中的test()方法 我们有两种方法

 

  • 传统方法    修改代码  重新编译 即可
     1 package reflection;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         // new Test1().test();
     7         new Test2().test();
     8 
     9     }
    10 
    11 }

     

  • 采用反射的方法  优点:不用修改代码  不用重新编译 
    • 提供一个配置文件 例如 Spring.txt 用来存储 两个类的 全限定名 
      Class=reflection.Test2
      

    • 重新编写main方法
      package reflection;
      
      import java.io.File;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.lang.reflect.Constructor;
      import java.lang.reflect.Method;
      import java.util.Properties;
      
      public class Main {
      
      	public static void main(String[] args) throws Exception, IOException {
      		// 传统的更改代码的方法
      		// new Test1().test();
      		// new Test2().test();
      
      		// 重新编写运用反射动态的加载一个类
      		// 1加载Spring.txt配置文件 读取你配置的要使用的类 下次如果更改类直接可以在配置文件更改
      		File file = new File("J:\\ecplisework\\testother\\src\\Spring.txt");
      		// 创建读取配置文件的对象properties
      		Properties Springtxt = new Properties();
      		// 使配置文件对象读取Spring.txt的内容
      		Springtxt.load(new FileInputStream(file));
      		// 获取Spring.txt中的class的值 也就使类的全限定名
      		String className = Springtxt.getProperty("class");
      		// 根据全限定名类创建类对象
      		Class<?> clazz = Class.forName(className);
      		// 获取方法对象
      		Method m = clazz.getMethod("test");
      		// 获取构造器
      		Constructor<?> c = clazz.getConstructor();
      		// 根据构造器 实例出一个对象
      		Object object = c.newInstance();
      		// 调用指定实例的指定方法
      		m.invoke(object);
      
      	}
      
      }
      

 

  • 总结:使用反射的方法不用去更改java代码 也不用去重新编译class文件就可以根据配置文件动态地反射加载一个类并运行其方法,只需要更改配置文件即可

3.为什么要使用反射&反射用在那些应用场景下

 

  • 正常创建一个类 new Object()的过程:当JVM启动,所有编写的类都会编译成.class文件,然后被类加载器加载进jvm的内存中,当需要创建一个类的实例的时候,JVM会先检查这个类是否加载,加载过了就寻找对应的.class对象,并为这个实例分配内存;
  • 突然-------我们突然想运行一个没有加载入JVM内存的类怎么办????? JVM里没有这个.class对象怎木办?????  这时反射就能帮助我们
  • 常见的应用场景例如在加载数据驱动的时候,可以通过配置文件来选择使用mysql数据库还是oracle数据库

4.如何更好的使用反射?

  • 作用:在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。对于任意一个对象,可以调用它的任意一个方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。
  • java的反射机制主要提供了一下功能  关键子:在运行时
    • 在运行时判断一个任意对象的所属的类
    • 在运行时构造一个任意类的对象
    • 在运行时判断任意类所具有的成员变量和方法
    • 在运行时调用任意对象的方法
  • 常用方法
    • 获取对象类型
      Class<?> clazz = Class.forName("类的权限定名");
      Class<? extends Test2> class1 = this.getClass();

      Classc2 =Test1.class;  

       

    • 获取构造器
      Constructor<?>[] constructors = clazz.getConstructors(); //获得类的所有公共构造函数
      

        

    • 获取字段信息的方法
      1         String name = clazz.getField("password").getName(); // 获得命名的公共字段 
      2         Field[] fields = clazz.getFields(); //获得所有公共字段
      3         Field declaredField = clazz.getDeclaredField("username"); //获得类声明的命名的字段
      4         Field[] declaredFields = clazz.getDeclaredFields(); //获取所有类声明的字段

       

    • 获取方法信息
      1         Method method = clazz.getMethod("test"); //使用特定的参数类型,获得命名的公共方法 
      2         Method[] methods = clazz.getMethods(); // 获得类的所有公共方法 
      3         Method declaredMethod = clazz.getDeclaredMethod("test"); //使用特写的参数类型,获得类声明的命名的方法 
      4         Field[] declaredFields2 = clazz.getDeclaredFields(); //获得类声明的所有方法

       

 





以上是关于厚积薄发系列之Java反射的主要内容,如果未能解决你的问题,请参考以下文章

细说java系列之反射

厚积薄发系列之JavaWeb的Filter

java反射系列五之获取类的完整结构

java反射系列四之创建运行时类的对象

java 反射代码片段

系统开发系列 之java反射以及应用补充