Java Reflection

Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于ReflectionAPO取得任何类的内部信息,

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

并能直接操作任意对象的内部属性及方法

Java反射机制提供的功能

》在运行时判断任意一个对象所属的类

》在运行时构造任意一个类的对象

》在运行时判断任意一个类所具有的成员变量和方法

》在运行时调用任意一个对象的成员变量和方法

》生成动态代理

 

主要内容:

  1.理解Class类并实例化Class类对象

  2.运行时创建类对象并获取类的完整结构

  3.通过反射调用类的指定方法、指定属性

  4.动态代理

 

反射相关的主要API:

java.lang.class:代表一个类

》java.lang.reflect.Method:代表类的方法

》java.lang.reflect.Field:代表类的成员变量

》java.lang.reflect.Construtor:代表类的构造方法

》。。。

 

1.理解Class类并实例化Class类对象
/*
* java.lang.Class:是反射的源头
*
* Class类
*
* 我们创建了一个类,通过编译(javac.exe),生成对应的.class文件。之后我们使用java.exe加载(JVM的类加载器完成的)此.class文件,
* 此.class文件加载到内存以后,就是一个运行时类,存放在缓存区。那么这个运行时类本身就是一个Class的实例!
* 1.每个运行时类只加载一次!
* 2.有了Class的实例以后,我们才可以进行如下的操作:
* 1)   创建对应的运行时类的对象
* 2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类、父类、所在包、异常、注解、。。。)
* 3)调用对应的运行时类的指定结构(属性、方法、构造器)
* 4)反射的应用:动态代理

 

* 在Object类中定义了此方法被所有子类继承:
* public final Class getClass()
*
* 正常方式:引入需要的“包类”名称——>通过new实例化——>取得实例化对象
* 反射方式:                 实例化对象——>getClass()方法——>得到完整的"包类"名称
*/

 //运用反射机制创建对象,并且调用方法和属性  @Test public void test1() throws Exception{ //1.创建反射调用运行时类的指定属性 Class clazz = Person.class; Person p1 = (Person) clazz.newInstance(); //2.通过反射调用运行时类的指定的属性 Field f1 = clazz.getField("name"); f1.set(p1,"Yhs"); System.out.println(p1);
Field f2
= clazz.getDeclaredField("age");//对权限为私有的属性进行调用 f2.setAccessible(true); f2.set(p1, 12); System.out.println(p1); //3.通过反射调用运行时类的指定的方法 Method m1 = clazz.getMethod("show"); m1.invoke(p1);//调用方法

Method m2 = clazz.getMethod("display", String.class); m2.invoke(p1, "HongKong"); }

 

 

 //如何获取Class的实例(3种)  @Test public void test3() throws ClassNotFoundException{ //1.调用运行时类本身的.class属性 Class clazz1 = Person.class; System.out.println(clazz1.getName());//reflect.Person Class clazz2 = String.class; System.out.println(clazz2.getName());//java.lang.String //2.通过运行时类的对象获取 Person p = new Person(); Class clazz3 = p.getClass(); System.out.println(clazz3.getName());//reflect.Person //3.通过Class的静态方法获取 String className="reflect.Person"; Class clazz4 = Class.forName(className); System.out.println(clazz4.getName());//reflect.Person //4.(了解)通过类的加载器 ClassLoader classLoader = this.getClass().getClassLoader(); Class clazz5 = classLoader.loadClass(className); System.out.println(clazz5.getName());//reflect.Person }

 

 

Java第十二章反射机制 随笔 第1张

 

 

 Java第十二章反射机制 随笔 第2张

类加载器ClassLoader:

 

 
        获取配置文件
    //法一:配置文件在具体的包内 ClassLoader loader = this.getClass().getClassLoader(); InputStream is = loader.getResourceAsStream("配置文件路径"); //法二:在当前目录下 FileInputStream is = new FileInputStream(new File("当前工程下配置文件的文件名")); Properties pros = new Properties(); pros.load(is); String name = pros.getProperty("user"); System.out.println(name); String password = pros.getProperty("password"); System.out.println(password);

Java第十二章反射机制 随笔 第3张

@Test public void test5(){ //获取系统类加载器 ClassLoader loader1 = ClassLoader.getSystemClassLoader(); System.out.println(loader1);//sun.misc.Launcher$AppClassLoader@456d3d51 //扩展类加载器 ClassLoader loader2 = loader1.getParent(); System.out.println(loader2);//sun.misc.Launcher$ExtClassLoader@456d3d51  
     //都属于核心类库,无法被获取 ClassLoader loader3
= loader2.getParent(); System.out.println(loader3);//null

     
String className = "java.lang.String";
    
     Class clazz1 = Class.forName(className);

          ClassLoader loader4 = clazz1.getClassLoader();
          System.out.println(loader5);

 }

 

2.运行时创建类对象并获取类的完整结构

创建类的对象:调用Class对象的newInstance()方法

要求:1)类必须有一个无参数的构造器

   2)类的构造器的访问权限需要足够

 String className1 ="reflect.Person"; Class clazz = Class.forName(className1); //创建对应的运行时类对象,使用newInstance(),实际上就是调用了运行时类的空参构造器 Object obj= clazz.newInstance();//调用了Person中的空参构造器。 Person p1 = (Person) obj; System.out.println(p1);

 

获取运行时类的属性结构

 @Test public void test1(){ Class clazz = Person.class; //getFields():只能获取到运行时类中及其父类声明为public的属性 Field[] f1 = clazz.getFields(); for(int i=0;i<f1.length;i++){ System.out.println(f1[i]); //public java.lang.String reflect.Person.name //public double reflect.Man.weight  } //getDeclaredFields():获取运行时类本身声明的所有属性。 Field[] f2 = clazz.getDeclaredFields(); for(Field f : f2 ){ System.out.println(f.getName()); //name //age //nation  } } @Test public void test2(){ Class clazz = Person.class; Field[] f1 = clazz.getDeclaredFields(); for (Field f : f1) { //权限修饰符 数据类型 属性名 //1.获取每个属性的权限修饰符,但用int型表示(0-default 1-public 2-private) int i = f.getModifiers(); System.out.print(i +" "); //把int型转换为权限修饰符,并用String类型表示 String str1 = Modifier.toString(i); System.out.print(str1 + " "); //2.获取属性的变量类型 Class type = f.getType(); System.out.print(type.getName() + " "); //3.获取属性名  System.out.print(f.getName()); System.out.println(); } }

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄