Java Class 类使用

Java Class 类使用

我们可以通过已知的包名来获取到 Class 对象,从而可以通过反射动态的来操作对象。
获取Class有三种方式

//通过对象.class直接获取
Class integerClass = Integer.class;

//根据包名,通过Class.forName方法获取class
Class integerClass = Class.forName("java.lang.Integer");

//根据包名,通过classloader.loadClass方法获取class
Class integerClass = this.getClass().getClassLoader().loadClass("java.lang.Integer");

接下来根据实际的例子说明一下

public interface InterfaceA {
    void interfaceAMethodA(int a);
}

public interface InterfaceB {
    Double interfaceBMethodB(int a, String b);
}

public class ClassA implements InterfaceA {

    private int classAFieldA;

    @Override
    public void interfaceAMethodA(int a) {

    }
    
    //省略了 getter setter 方法
}

public class ClassB extends ClassA implements InterfaceB{

    private String classBFieldB;

    @Override
    public Double interfaceBMethodB(int a, String b) {
        return null;
    }
    
    //省略了 getter setter 方法
}

运行一个测试方法

public static void main(String[] args) {
    Class clazz = Class.forName("org.dmgnn.reflect.ClassB");
        
    System.out.println("clazz.getGenericSuperclass() = " + JSON.toJSONString(clazz.getGenericSuperclass()));
    System.out.println("clazz.getSuperclass() = " + JSON.toJSONString(clazz.getSuperclass()));

    Arrays.stream(clazz.getMethods()).forEach(m -> {
    System.out.println("clazz.getMethods() -> " + m.getName() + " getParameterTypes -> " + JSON.toJSONString(m.getParameterTypes()) + " getReturnType -> " + m.getReturnType());
    });

    Arrays.stream(clazz.getDeclaredMethods()).forEach(m -> {
        System.out.println("clazz.getDeclaredMethods() -> " + m.getName() + " getParameterTypes -> " + JSON.toJSONString(m.getParameterTypes()) + " getReturnType -> " + m.getReturnType());
    });


    System.out.println("clazz.getInterfaces() = " + JSON.toJSONString(clazz.getInterfaces()));

    System.out.println("clazz.getGenericInterfaces() = " + JSON.toJSONString(clazz.getGenericInterfaces()));
}


//输出
clazz.getGenericSuperclass() = "org.dmgnn.reflect.ClassA"
clazz.getSuperclass() = "org.dmgnn.reflect.ClassA"
 
clazz.getMethods() -> equals getParameterTypes -> ["java.lang.Object"] getReturnType -> boolean
clazz.getMethods() -> toString getParameterTypes -> [] getReturnType -> class java.lang.String
clazz.getMethods() -> hashCode getParameterTypes -> [] getReturnType -> int
clazz.getMethods() -> builder getParameterTypes -> [] getReturnType -> class org.dmgnn.reflect.ClassB$ClassBBuilder
clazz.getMethods() -> interfaceBMethodB getParameterTypes -> ["int","java.lang.String"] getReturnType -> class java.lang.Double
clazz.getMethods() -> getClassBFieldB getParameterTypes -> [] getReturnType -> class java.lang.String
clazz.getMethods() -> setClassBFieldB getParameterTypes -> ["java.lang.String"] getReturnType -> void
clazz.getMethods() -> interfaceAMethodA getParameterTypes -> ["int"] getReturnType -> void
clazz.getMethods() -> getClassAFieldA getParameterTypes -> [] getReturnType -> int
clazz.getMethods() -> setClassAFieldA getParameterTypes -> ["int"] getReturnType -> void
clazz.getMethods() -> wait getParameterTypes -> ["long","int"] getReturnType -> void
clazz.getMethods() -> wait getParameterTypes -> ["long"] getReturnType -> void
clazz.getMethods() -> wait getParameterTypes -> [] getReturnType -> void
clazz.getMethods() -> getClass getParameterTypes -> [] getReturnType -> class java.lang.Class
clazz.getMethods() -> notify getParameterTypes -> [] getReturnType -> void
clazz.getMethods() -> notifyAll getParameterTypes -> [] getReturnType -> void
 
clazz.getDeclaredMethods() -> equals getParameterTypes -> ["java.lang.Object"] getReturnType -> boolean
clazz.getDeclaredMethods() -> toString getParameterTypes -> [] getReturnType -> class java.lang.String
clazz.getDeclaredMethods() -> hashCode getParameterTypes -> [] getReturnType -> int
clazz.getDeclaredMethods() -> canEqual getParameterTypes -> ["java.lang.Object"] getReturnType -> boolean
clazz.getDeclaredMethods() -> builder getParameterTypes -> [] getReturnType -> class org.dmgnn.reflect.ClassB$ClassBBuilder
clazz.getDeclaredMethods() -> getClassBFieldB getParameterTypes -> [] getReturnType -> class java.lang.String
clazz.getDeclaredMethods() -> interfaceBMethodB getParameterTypes -> ["int","java.lang.String"] getReturnType -> class java.lang.Double
clazz.getDeclaredMethods() -> setClassBFieldB getParameterTypes -> ["java.lang.String"] getReturnType -> void

clazz.getInterfaces() = ["org.dmgnn.reflect.InterfaceB"]
 
clazz.getGenericInterfaces() = ["org.dmgnn.reflect.InterfaceB"]
 

getGenericSuperclass() 和 getSuperclass() 返回父类class
getMethods() 返回当前class以及父类class的所有方法 getDeclaredMethods 返回当前class的方法 getInterfaces() 和 getGenericInterfaces() 返回当前class实现的接口

Type 接口

getGenericSuperclass() 和 getSuperclass() 虽然都是返回的父类class,但是2个方法的返回类型不一样。

public Type getGenericSuperclass() {
    ClassRepository info = getGenericInfo();
    if (info == null) {
        return getSuperclass();
    }

    // Historical irregularity:
    // Generic signature marks interfaces with superclass = Object
    // but this API returns null for interfaces
    if (isInterface()) {
        return null;
    }

    return info.getSuperclass();
}

public native Class<? super T> getSuperclass();

getSupperClass() 返回的是Class<? super T>
getGenericSuperClass() 返回的是 Type

/**
 * Type is the common superinterface for all types in the Java
 * programming language. These include raw types, parameterized types,
 * array types, type variables and primitive types.
 *
 * @since 1.5
 */
public interface Type {
    /**
     * Returns a string describing this type, including information
     * about any type parameters.
     *
     * @implSpec The default implementation calls {@code toString}.
     *
     * @return a string describing this type
     * @since 1.8
     */
    default String getTypeName() {
        return toString();
    }
}

从注释来看,Type 接口是 Java 编程语言中所有类型的通用超级接口。这些包括原始类型,参数化类型,数组类型,类型变量和基本数据类型。 已知的子接口有 GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType

ParameterizedType 使用

ParameterizedType 定义为

public interface ParameterizedType extends Type {

    //返回的对象的实际类型参数 Type代表这种类型的数组。
    Type[] getActualTypeArguments();

    //返回表示的类或接口声明此类型的 Type对象。
    Type getRawType();

    //返回一个表示该类型的成员 Type对象类型。
    Type getOwnerType();
}    

看注释有点看不懂,再看一个例子

public class ClassC<T1, T2> {

    public void printType() {
        System.out.println("clazz.getGenericSuperclass() = " + JSON.toJSONString(getClass().getGenericSuperclass()));
        System.out.println("clazz.getActualTypeArguments() = " + JSON.toJSONString(((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()));
    }

}

public class ClassD extends ClassC<Integer, String> {
}

public static void main(String[] args) {
    ClassD classD = new ClassD();
    classD.printType();
}

//输出
clazz.getGenericSuperclass() = {"actualTypeArguments":["java.lang.Integer","java.lang.String"],"rawType":"org.dmgnn.reflect.ClassC","typeName":"org.dmgnn.reflect.ClassC<java.lang.Integer, java.lang.String>"}
clazz.getActualTypeArguments() = ["java.lang.Integer","java.lang.String"]

clazz.getGenericSuperclass() 获取到的是ClassD的父类,也就是ClassC<T1, T2>,这个类接收2个泛型参数。
通过打印出来的日志看到已经获取到了ClassC实际运行时的参数(actualTypeArguments)类型为<Integer, String>,也就是ClassD在继承的时候传到ClassC的参数,原型(rawType)为 org.dmgnn.reflect.ClassC,完整的类名(typeName)为 org.dmgnn.reflect.ClassC<java.lang.Integer, java.lang.String>
那么想要获得ClassC在运行的时的泛型类型,只要调用getActualTypeArguments()方法即可。

转载于:https://my.oschina.net/u/232911/blog/1832246

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值