Java 中的反射

反射的概念

根据某个对象来获取该对象所对应的类的完整信息。

反射的功能

  1. 可以判断运行时对象所属的类;
  2. 可以判断运行时对象所包含的成员变量和方法。

Java 反射机制中的类

java.lang.Class
java.lang.reflect.Constructor
java.lang.reflect.Field
java.lang.reflect.Method
java.lang.reflect.Modifier

类类型

在 Java 中,万物皆对象,Object 类是所有类的父类,所有类的实例化对象都是 Class 类的对象,Class 类的对象称为类类型。

获取一个类的类类型的方法

首先,我们有一个 Person 类,如下:

package reflecttest;

public class Person {
    
    // 定义 private 修饰的成员变量
    private String name;
    private int age;
    
    // 定义一个无参构造方法
    public Person() {
        
    }

    // 定义一个 public 修饰的带参数构造方法
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    // get set 方法
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    // 重写 toString() 方法
    @Override
    public String toString() {
        return name + ", " + age;
    }
    
}

1. 对象.getClass()

任何一个类都继承了 Object 类,因此也继承了 getClass() 方法,通过该类的对象调用 getClass() 方法可以得到该类的类类型。

public class Test01 {
    
    public static void main(String[] args) {

        Person p = new Person();
        Class c1 = p.getClass();
        // 取得类名
        System.out.println(c1);
        // 取得包名
        System.out.println(c1.getName());

    }
    
}

运行结果:


2. 类名.class

每个类中都隐含了一个静态属性 class,通过 类名.class,也可以获得该类的类类型。

public class Test01 {
    
    public static void main(String[] args) {
        
        Class c2 = Person.class;
        // 取得类名
        System.out.println(c2);
        // 取得包名
        System.out.println(c2.getName());
        
    }
    
}

运行结果:


3. Class.forName

通过动态加载类,Class.forName(“类名的全称(包含包名)”),Class.forName 必须抛出异常或对异常进行捕获处理。

public class Test01 {
    
    public static void main(String[] args) {
        
        try {
            Class c3 = Class.forName("reflecttest.Person");
            // 取得类名
            System.out.println(c3);
            // 取得包名
            System.out.println(c3.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
    }
    
}

运行结果:


注: 静态加载,在编译时加载的类称为静态加载类;动态加载,在运行时加载的类称为动态加载类。

通过一个类的类类型获取该类的详细信息

获得一个类的类类型后,可以创建该类对象,并且反射出该类中的方法和属性。

1. 通过类类型创建对象

public class Test02 {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        
            Person p1 = new Person();
            Class c1 = p1.getClass();
            Person p2 = (Person) c1.newInstance();
            
            Class c2 = Person.class;
            Person p3 = (Person) c2.newInstance();
            
            Class c3 = Class.forName("reflecttest.Person");
            Person p4 = (Person) c3.newInstance();
            
            // 得到类类型所代表的类名的全称,包含包名
            System.out.println(c3.getName());
            // 得到类类型所代表的类名,不包含类名
            System.out.println(c3.getSimpleName());
        
    }

}

运行结果:


注意: 通过类类型创建对象时,该类必须要有无参的构造方法。

2. 通过类类型反射出该类中所有的属性

在 Java 中,万物皆对象,属性也是对象,它是 Feild 类的对象。

方法 描述
getFeilds() 获得该类的所有公有属性,包括该类从父类中继承的
getDeclaredFields() 获得所有该类自己声明的属性,不论访问权限
getField(name) 根据给定属性名得到公有的属性的类

通过类类型反射出该类中所有的方法

在 Java 中,万物皆对象,方法也是对象,它是 Method 类的对象。

方法 描述
getMethods() 获得该类的所有 public 方法,包括从父类中继承的和从接口实现的方法
getDeclaredMethods() 获得所有该类自己声明的方法,不论访问权限
getMethod(Sting name, Class... parameterTypes) 根据指定方法和参数列表得到相应的公有方法,包括包括从父类中继承的和从接口实现的方法
getDeclaredMethod(Sting name, Class... parameterTypes) 根据指定方法和参数列表得到该类自己的公有方法

通过类类型反射出该类的所有构造方法

在 Java 中,万物皆对象,构造方法也是对象,它是 Constructor 类的对象。

方法 描述
getDeclaredConstructors() 得到该类的全部构造方法,不论访问权限
getConstructors() 得到该类的公有构造方法

参考资料:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 什么是反射 Java 反射是可以让我们在运行时获取类的函数、属性、父类、接口等 Class 内部信息的机制。 能做...
    红烧排骨饭阅读 533评论 0 1
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,560评论 18 399
  • 作为一个艺术家,能够使我兴奋的事情莫过于将垃圾转化成艺术品啦!小时候的贫瘠生活,使得我更加懂得如何将废物再利用,同...
    youngliang阅读 436评论 2 4
  • 驰骋沙场,非一日之匹夫。千里溃堤,非一朝之蚁掘。涅槃重生,非一日之挣扎。流星陨落,非一日之裂变。诚然,万般宇宙...
    暗黑魔法师阅读 1,991评论 0 0