JDK源码阅读(四) : 反射——Class

本文详细探讨了Java中的Class类,包括获取Class对象的三种方式、将Class对象转换为字符串的方法、获取类的加载器、成员字段、成员方法、构造器以及资源的方法。通过对Class对象的操作,我们可以深入理解Java的反射机制。
摘要由CSDN通过智能技术生成

1. 什么是Class

java中一切皆对象。java中所有的类或接口(enum或annotation也是一种接口)其实都是对象,它们都是Class类的实例。数组类型也是一种Class对象,它抽象了所有元素类型相同且维度相同的数组。基础数据类型(比如int、byte)也可以作为Class类的对象。

2. 获取Class对象

Class对象是在类加载时由java虚拟机自动创建的。

/*
 * 构造器为private,只有JVM才能创建Class对象
 */
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;
}

(1)我们可以通过对某个对象obj调用它的getClass方法就可以获取到这个对象所属类的Class对象。比如:

Number n = 0;
Class<? extends Number> c = n.getClass();

getClass方法被定义Object类中。该方法返回调用对象的运行时类。注意到,真实的返回值类型应该是这个调用对象类的超类。

    /**
     * <p><b>The actual result type is {@code Class<? extends |X|>}
     * where {@code |X|} is the erasure of the static type of the
     * expression on which {@code getClass} is called.
     *
     */
public final native Class<?> getClass();

此外,如果我们对泛型对象调用getClass方法类获取其运行时类对象,将无法获取到泛型信息,因为在java中的泛型信息在编译期都会被擦除。比如:

List<Integer> list = new ArrayList<>();
Class<? extends List> aClass = list.getClass();
System.out.println(aClass);//结果是class java.util.ArrayList

(2)通过形如String.class的方式获取到类的Class对象,“."号前为类的字面名称。比如:

Class<String> stringClass = String.class;

(3)通过调用Class类中的forName方法来获取Class对象,参数为类的完整名称(具体到哪个包下的哪个类)。比如:

Class<?> string = Class.forName("java.lang.String");

其中的Class<?>等价于Class。

3. 将Class对象转换成字符串

3.1 toString()方法

该方法将一个Class对象转化为一个字符串。

首先,判断该对象是interface、基本数据类型还是class,然后调用getName方法获得全类名。

如果这个Class对象表示的是基本数据类型,则getName会返回基本类型的名称;

如果表示的是void类型,则getName会返回“void"。

public String toString() {
   
    return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
        + getName();
}

比如:

String str = "abc";
Class strClass = str.getClass();
String s1 = strClass.toString();
System.out.println(s1);//得到class java.lang.String

3.2 toGenericString()方法

该方法返回更详细的类信息,除了全类名外,还包括修饰符和泛型类型参数。比如:

Map<Integer,String> map = new HashMap<>();
Class<? extends Map> mapClass = map.getClass();
String s = mapClass.toGenericString();
System.out.println(s);//得到 public class java.util.HashMap<K,V>

下面具体来看toGenericString方法。

public String toGenericString() {
   
  	//如果是原始数据类型,则不存在修饰符和类型信息
    if (isPrimitive()) {
   
        return toString();
    } else {
   
      	//新建一个StringBuilder对象,用于拼接各类信息
        StringBuilder sb = new StringBuilder(
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值