反射-基本了解(Class类)

本文介绍了Java中获取类对象的三种方法,强调了使用全限定名的必要性以避免ClassNotFoundException。通过Class类,可以获取类中的属性、方法等详细信息。对于private属性,虽然publicFields为空,但能获取其类型和名称。文章还展示了Modifier类中关于修饰符的表示方式,并指出在Class中获取的属性、方法都是对象,提供了丰富的操作方法。重点提到了Method类的invoke方法,用于调用对象的方法,非静态方法需传入实例,静态方法则可传入null。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Use类

public class User {

    private String name;

    private double height;

    private Date birthday;

    public User(String name, double height, Date birthday) {
        this.name = name;
        this.height = height;
        this.birthday = birthday;
    }

    public User() {

    }

    public String getName() {
        return name;
    }

    public double getHeight() {
        return height;
    }

    public Date getBirthday() {
        return (Date) birthday.clone();
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Double.compare(user.height, height) == 0 &&
                name.equals(user.name) &&
                birthday.equals(user.birthday);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, height, birthday);
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", birthday=" + new SimpleDateFormat("yyyy-MM-dd").format(birthday) +
                '}';
    }
}

首先介绍三种 获取类对象的方法

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd")//日期格式化对象
User tom = new User("Tom Galas",178.6,sdf.parse("1997-08-24"));
Class aClass = tom.getClass();//根据实例获取类对象
aClass = User.class;//根据类获取类对象
aClass = Class.forName("reflection.User");//根据类名(全限定名)获取类对象

特别注意:根据类名获取类对象 一定要使用全限定名,否则报

java.lang.ClassNotFoundException: User

获取到类之后我们就可以获取到类中的全部东西了。
首先来获取属性

Field[] allFields = aClass.getDeclaredFields();//可以获取包括private修饰的全部属性
Field[] publicFields = aClass.getFields();//只能获取public修饰的属性
for (Field field : allFields) {
 //getType是获取属性的类型                     getName是获取属性的变量名
	System.out.println(field.getType() + "-->" + field.getName());
}
System.out.println("========================");
for (Field field : publicFields) {
	System.out.println(field.getType() + "-->" + field.getName());
}

因为User类中的所有属性都是private修饰的,所以毫无疑问publicFields数组是空的
输出结果如下:

class java.lang.String–>name
double–>height
class java.util.Date–>birthday
========================

不单单是属性的类型和属性名,甚至连属性的修饰符都能够获取到

Field[] allFields = aClass.getDeclaredFields();//可以获取包括private修饰的全部属性

for (Field field : allFields) {
	//getType是获取属性的类型                     getName是获取属性的变量名
	System.out.println(field.getModifiers() + "-->" + field.getType() + "-->" + field.getName());
            }

运行结果:

2–>class java.lang.String–>name
2–>double–>height
2–>class java.util.Date–>birthday

会显示2,这是在Modifier类中规定的
下面抽取Modifier中一小段代码展示

 /**
     * The {@code int} value representing the {@code public}
     * modifier.
     */
    public static final int PUBLIC           = 0x00000001;

    /**
     * The {@code int} value representing the {@code private}
     * modifier.
     */
    public static final int PRIVATE          = 0x00000002;

    /**
     * The {@code int} value representing the {@code protected}
     * modifier.
     */
    public static final int PROTECTED        = 0x00000004;

    /**
     * The {@code int} value representing the {@code static}
     * modifier.
     */
    public static final int STATIC           = 0x00000008;

    /**
     * The {@code int} value representing the {@code final}
     * modifier.
     */
    public static final int FINAL            = 0x00000010;
    ......

可以看出在源码中使用16进制来代表不同的修饰符的。
private是2。

我们要深知一点,在java中,一切都是对象。所以我们在Class中获取到的属性,方法等,他们也都是对象,在他们其中有编写好的操作他们的方法。

Constructor[] declaredConstructors = aClass.getDeclaredConstructors();//获取全部构造器
Annotation[] declaredAnnotations = aClass.getDeclaredAnnotations();//获取类上的全部注解(不是类中)
Method[] declaredMethods = aClass.getDeclaredMethods();//获取全部方法

还有许多方法可以前往Class类中查看。你会有很大收获。
许多方法的使用都大差不差。

在这里特别注意的是在Method中有个invoke方法

Method getName = aClass.getMethod("getName");//根据方法名获取方法对象
getName.invoke(tom);//调用tom实例中的getName方法,这里因为,getName没有参数,所以不需要传任何东西,如果有参数,则在tom后依次传入,使用标点隔开,如invoke(tom,1,2,3,..)

这里的getName方法不是static修饰的,所以需要传入User对象的一个实例,如果该方法是static修饰的,那么invoke的第一个参数直接传入null(注意是传入null,而不是不传)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值