栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java基础-反射机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java基础-反射机制

概述

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

反射的基础

除了int等基本类型外,Java的其他类型全部都可以认为是class(包括interface)。
由于JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息,包括类名、包名、父类、实现的接口、方法、字段等,因此,如果获取了实例对应的Class实例,就可以通过这个Class实例获取到该实例对应的class的所有信息。

获取class的Class实例
// 以String为例
//方法一:直接通过一个class的class静态变量获取
Class class1 = String.class;
//方法二:通过实例变量提供的getClass()方法获取
String s = "";
Class class2 = s.getClass();
//方法三:如果知道一个class的完整类名,可以通过静态方法Class.forName()获取:
Class class3 = Class.forName("java.lang.String");
访问字段

对任意的一个实例,只要我们获取了它的Class,就可以获取它的一切信息。
Class类提供了以下几个方法来获取字段:
Field getField(name):根据字段名获取某一个public权限的字段(包括父类)
Field getDeclaredField(name):根据字段名获取当前类的某一个public权限的字段(不包括父类)
Field[] getFields():获取public权限的所有字段(包括父类)
Field[] getDeclaredFields():获取当前类的所有字段(不包括父类)
这里只展示单个字段的获取

public class Main {
    public static void main(String[] args) throws Exception {
        //获取Student的Class实例
        Class stdClass = Student.class;
        // 获取Student的public字段"score":
        System.out.println(stdClass.getField("score"));
        // 获取Student父类的public字段"name":
        System.out.println(stdClass.getField("name"));
        // 获取Student的private字段"grade":
        System.out.println(stdClass.getDeclaredField("grade"));
    }
}

class Student extends Person {
    public int score;
    private int grade;
}
class Person {
    public String name;
 }

输出结果

public int one.Student.score
public java.lang.String one.Person.name
private int one.Student.grade

若使用stdClass.getField(“grade”)获取private字段,则会报错如

Exception in thread "main" java.lang.NoSuchFieldException: grade
 at java.lang.Class.getField(Class.java:1703)
 at one.Main.main(Main.java:xx)
访问方法

Class实例获取所有Field对象,同样的,可以通过Class实例获取所有方法。Class类提供了以下几个方法来获取方法:
Method getMethod(name, Class…):获取某一个public方法(包括父类)
Method getDeclaredMethod(name, Class…):获取当前类的某一个方法(不包括父类)
Method[] getMethods():获取所有public的方法(包括父类)
Method[] getDeclaredMethods():获取当前类的所有方法(不包括父类)
使用方法和访问字段相同,就不多展示
但调用非public方法时虽然可以通过Class.getDeclaredMethod()获取该方法实例,但直接对其调用将得到一个IllegalAccessException。为了调用非public方法,我们通过Method.setAccessible(true)允许其调用:

public class Main {
public static void main(String[] args) throws Exception {
    Person person = new Person();
    // 获取Person的Class实例
    Class class1 = person.getClass();
    // 获取Class实例的方法
    Method m = class1.getDeclaredMethod("setName", String.class);
    // 允许对private进行操作
    m.setAccessible(true);
    // 执行person的方法
    m.invoke(person, "Bob");
    //验证操作是否成功
    System.out.println("personName = " + person.name);
  }
}
class Person {
    String name;
    private void setName(String name) {
        this.name = name;
    }
}
personName = Bob
访问构造方法

如果通过反射来创建新的实例,可以调用Class提供的newInstance()方法:
Person p = Person.class.newInstance();
但它只能调用该类的public无参数构造方法。如果构造方法带有参数,或者不是public,就无法直接通过Class.newInstance()来调用。
为了调用任意的构造方法,Java的反射API提供了Constructor对象,包含一个构造方法的所有信息,可以创建一个实例。Constructor对象和Method非常类似,不同之处仅在于它是一个构造方法,并且,调用结果总是返回实例:
通过Class实例获取Constructor的方法如下:
getConstructor(Class…):获取某个public的构造方法;
getDeclaredConstructor(Class…):获取某个构造方法;
getConstructors():获取所有public的构造方法;
getDeclaredConstructors():获取所有构造方法。

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1017559.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号