一. 什么是反射
在运行状态中,对于任意一个类,都能够知道其所有属性和方法,对于任意一个对象,都能够调用其任意方法和属性,这种动态获取信息、动态调用方法的能力称为Java语言的反射机制,大部分框架都有用到反射机制,了解反射的使用方法非常重要。
 
ASP站长网一个类通常包含了属性、方法、构造函数等,而Java一般情况下是现有类再有对象,通过对象调用各种属性和方法,而Java反射则是通过已有的对象,反过来得到其所属类的相关信息,调用所属类的相关方法。
 
二. 反射的基础Class
2.1 Class类概述
我们知道在Java的世界中,万事万物皆对象。其实类本身也是对象,任何一个类都是Class类的实例对象。
 
//定义了一个SuperHero的类
public class SuperHero {}
如上面定义的SuperHero类,是类也是对象,
 
对象:SuperHero类是Class类的实例,Class类是SuperHero的类类型,故而为对象;
 
类:以类的方式创建,SuperHero本身可以调用SuperHero ironMan = new SuperHero ()被实例化,ironMan 就是创建的实体,故而也是类。
 
 
 
Class类很特殊,它表示了某个类的类类型,被不可被继承,每个类的Class对象仅有一个,Class类没有公共构造函数。 相反, Class对象由Java虚拟机自动构建,因为加载了类,并且通过调用类加载器中的defineClass方法,原始Java类型( boolean , byte , char , short , int , long , float和double ),和关键字void也表示为Class对象
 
//Class源码,final修饰不可被继承,构造函数是private的,不可手动实例化
public final class Class<T> {
    private Class(ClassLoader loader) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
    }
}
public static void main(String[] args) {
    try {
        Class clazz1 = Class.forName("java.lang.Integer");
        Class clazz2 = Class.forName("java.lang.Integer");
        System.out.println(clazz1 == clazz2);
        System.out.println(int.class);
        System.out.println(void.class);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}
运行结果为:
 
true
int
void
2.2 Class类对象获取的三种方式
先定义一个类
 
package reflectdemo;
import java.io.Serializable;
 
/**
 * 超级英雄类
 */
public class SuperHero implements Serializable {
    
    public static final String ADDRESS = "earth";
    
    private String id;
 
    private String name;
 
    private Integer age;
 
    private String skill;
 
    public SuperHero() {
    }
 
    public SuperHero(String id, String name, Integer age, String skill) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.skill = skill;
    }
 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
    public String getSkill() {
        return skill;
    }
 
    public void setSkill(String skill) {
        this.skill = skill;
    }
    
    public void print(){
        System.out.println("超级英雄:" + this.name);
    }
}
2.2.1 通过对象获取Class
public static void main(String[] args) {
    SuperHero ironMan = new SuperHero("1","钢铁侠",35, "战甲");
    Class clazz = ironMan.getClass();
    System.out.println(clazz.getName());
}
输出结果:
 
reflectdemo.SuperHero
2.2.2 通过类获取Class
public static void main(String[] args) {
    Class clazz = SuperHero.getClass();
    System.out.println(clazz.getName());
}
输出结果:
 
reflectdemo.SuperHero
2.2.3 传入类路径获取Class
public static void main(String[] args) {
    try {
        Class clazz = Class.forName("reflectdemo.SuperHero");
        System.out.println(clazz.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}
输出结果:
 
reflectdemo.SuperHero
三种创建方式:
 
第一种方式对象已经有了,所有的操作直接通过该对象进行即可,
 
第二种方式需要import将类引入,也不是常用的方式,
 
第三种仅需传入类的路径,即可得到类的相关信息,是最常用的方式。
 
2.2.4 获取类信息的常用方法
public static void main(String[] args) {
    try {
        Class clazz = Class.forName("reflectdemo.SuperHero");
        //获取类名称(含路径)
        System.out.println(clazz.getName());
        //获取类名称(不含路径)
        System.out.println(clazz.getSimpleName());
        //获取所在包
        System.out.println(clazz.getPackage());
 
        //通过Class创建对象
        SuperHero hero = (SuperHero)clazz.newInstance();
        
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}
输出结果:
 
reflectdemo.SuperHero
SuperHero
package reflectdemo
这里提前说明一下:Class中两个功能相同的方法,若其中一个带有Declared字样,表示针对类中所有声明的变量、方法、构造函数等,而对应不带Declared字样的方法,则表示仅对公有(public)成员变量、方法起作用,下面不再重复描述,下面仅对带有Declared字样的方法进行讲解。

dawei

【声明】:九江站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。