Java Class 類使用

Java Class 類使用

咱們能夠經過已知的包名來獲取到 Class 對象,從而能夠經過反射動態的來操做對象。
獲取Class有三種方式java

//經過對象.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個方法的返回類型不同。ide

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>, WildcardTypeui

ParameterizedType 使用

ParameterizedType 定義爲this

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()方法便可。code

相關文章
相關標籤/搜索