程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 反射——類(Class),反射class

反射——類(Class),反射class

編輯:JAVA綜合教程

反射——類(Class),反射class


本文原創,轉載請注明原處!

 

 

紅色代表的是基本組件:包(Package),修飾符(modifier),類(Class),字段(Field),構造器(Constructor)和方法(Method)。

黃色代表的是泛型組件:可定義泛型的元素(GenericDeclaration),類型(Type),泛型(TypeVariable),泛型參數類(ParameterizedType),泛型數組(GenericArrayType),通配符(WildcardType)。

藍色代表的是注解組件:可被注解的元素(AnnotatedElement),注解後的類型(AnnotatedType),注解(Annotation),其它。

 

類(Class)

類不是單純的指class定義的類,它是包括基本數據類型和數組,還包括class,interface,@interface,enum等定義出來的類型。

平常所用到的,所定義出來的類型,都可以歸為現在所講述的這個“類”,但它不包括泛型,雖然說泛型可以作為一個類型來使用。 

接口:Type,GenericDeclaration,AnnotatedElement

 

名稱

  • getName():String
  • getCanonicalName():String
  • getSimpleName():String
  • s+forName(String):Class<?>
  • s+forName(String, boolean, ClassLoader):Class<?>

示例:

public class Test {
    public static void main(String[] params) throws ClassNotFoundException {
        Class<?> clazz = Class.forName("test.TestClass$TestInnerClass");
        System.out.println(clazz.getName());
        System.out.println(clazz.getCanonicalName());
        System.out.println(clazz.getSimpleName());
        
        /*
            運行結果:
            test.TestClass$TestInnerClass
            test.TestClass.TestInnerClass
            TestInnerClass
         */
    }
}

test/TestClass.java

public class TestClass {
    public class TestInnerClass {
        
    }
}

  

類型

  • isPrimitive():boolean
    查看是否基本數據類型。
  • isArray():boolean
    查看是否數組類型。
  • isInterface():boolean
    查看是否接口類型。
  • isAnnotation():boolean
    查看是否注解類型。
  • isEnum():boolean
    查看是否枚舉類型。
public class Test {
    public static void main(String[] params) {
        print("基本數據類型", int.class);
        /*
            輸出結果:
            基本數據類型 -> 是否基本數據類型=true
            基本數據類型 -> 是否數組=    false
            基本數據類型 -> 是否接口=    false
            基本數據類型 -> 是否注解=    false
            基本數據類型 -> 是否枚舉=    false
         */
        
        System.out.println("-------------------------");
        print("數組", int[].class);
        /*
            輸出結果:
            數組 -> 是否基本數據類型=false
            數組 -> 是否數組=    true
            數組 -> 是否接口=    false
            數組 -> 是否注解=    false
            數組 -> 是否枚舉=    false
         */
        
        System.out.println("-------------------------");
        print("接口", TestInterface.class);
        /*
            輸出結果:
            接口 -> 是否基本數據類型=false
            接口 -> 是否數組=    false
            接口 -> 是否接口=    true
            接口 -> 是否注解=    false
            接口 -> 是否枚舉=    false
         */
        
        System.out.println("-------------------------");
        print("注解", TestAnnotation.class);
        /*
            輸出結果:
            注解 -> 是否基本數據類型=false
            注解 -> 是否數組=    false
            注解 -> 是否接口=    true
            注解 -> 是否注解=    true
            注解 -> 是否枚舉=    false
         */
        
        System.out.println("-------------------------");
        print("枚舉", TestEnum.class);
        /*
            輸出結果:
            枚舉 -> 是否基本數據類型=false
            枚舉 -> 是否數組=    false
            枚舉 -> 是否接口=    false
            枚舉 -> 是否注解=    false
            枚舉 -> 是否枚舉=    true
         */
        
        System.out.println("-------------------------");
        print("類", TestClass.class);
        /*
            輸出結果:
            類 -> 是否基本數據類型=false
            類 -> 是否數組=    false
            類 -> 是否接口=    false
            類 -> 是否注解=    false
            類 -> 是否枚舉=    false
         */
    }
    
    public static void print(String name, Class<?> clazz){
        System.out.println(name + " -> 是否基本數據類型=" + clazz.isPrimitive());
        System.out.println(name + " -> 是否數組=\t" + clazz.isArray());
        System.out.println(name + " -> 是否接口=\t" + clazz.isInterface());
        System.out.println(name + " -> 是否注解=\t" + clazz.isAnnotation());
        System.out.println(name + " -> 是否枚舉=\t" + clazz.isEnum());
    }

    public static class TestClass { }
    public static interface TestInterface { }
    public static @interface TestAnnotation { }
    public static enum TestEnum { }
}

注意:注解既是注解類型,又是接口類型,但它不能像接口一樣,可以被實現。

  • getComponentType():Class<?>
    該類為數組類型時,可通過此方法獲取其組件類型。

示例:

public class Test {
    public static void main(String[] params) {
        System.out.println(int[].class.getComponentType());
        System.out.println(int[][].class.getComponentType());
        
        /*
            輸出結果:
            int
            class [I
         */
    }
}

 

  • getPackage():Package
    獲取類在定義時所在的包。

 

修飾符

  • getModifiers():int

示例:

public class Test {
    public static void main(String[] params) {
        System.out.println(Modifier.toString(TestClass.class.getModifiers()));
        
        // 輸出結果:
        // public static final
    }
    
    public static final class TestClass {
        
    }
}

 

內部定義

網絡上查閱中,其中對內部類的劃分有常規內部類,靜態內部類,局部內部類,匿名內部類。下面的述語中,成員內部類是指常規內部類與靜態內部類。

  • getDeclaringClass():Class<?>
    獲取成員內部類在定義時所在的類。
  • getEnclosingClass():Class<?>
    獲取內部類在定義時所在的類。
  • getEnclosingConstructor():Constructor
    獲取局部或匿名內部類在定義時所在的構造器。
  • getEnclosingMethod():Method
    獲取局部或匿名內部類在定義時所在的方法。
  • isMemberClass():boolean
    查看是否成員內部類。
  • isLocalClass():boolean
    查看是否局部內部類。
  • isAnonymousClass():boolean
    查看是否匿名內部類。

示例:

public class Test {
    public static void main(String[] params) {
        new Test().test();
    }
    
    public void test(){
        printInnerClass("常規內部類", Test.InnerClass.InnerClass2.class);
        /*
            輸出結果:
            常規內部類 -> DeclaringClass=    class Test$InnerClass
            常規內部類 -> EnclosingClass=    class Test$InnerClass
            常規內部類 -> EnclosingConstructor=null
            常規內部類 -> EnclosingMethod=    null
            常規內部類 -> 是否成員內部類=    true
            常規內部類 -> 是否局部內部類=    false
            常規內部類 -> 是否匿名內部類=    false
         */

        System.out.println("---------------------------------------------------------------------------------------");
        printInnerClass("靜態內部類", StaticInnerClass.StaticInnerClass2.class);
        /*
            輸出結果:
            靜態內部類 -> DeclaringClass=    class Test$StaticInnerClass
            靜態內部類 -> EnclosingClass=    class Test$StaticInnerClass
            靜態內部類 -> EnclosingConstructor=null
            靜態內部類 -> EnclosingMethod=    null
            靜態內部類 -> 是否成員內部類=    true
            靜態內部類 -> 是否局部內部類=    false
            靜態內部類 -> 是否匿名內部類=    false
         */

        System.out.println("---------------------------------------------------------------------------------------");
        class LocalInnerClass { }
        printInnerClass("局部內部類", LocalInnerClass.class);
        /*
            輸出結果:
            局部內部類 -> DeclaringClass=    null
            局部內部類 -> EnclosingClass=    class Test
            局部內部類 -> EnclosingConstructor=null
            局部內部類 -> EnclosingMethod=    public void Test.test()
            局部內部類 -> 是否成員內部類=    false
            局部內部類 -> 是否局部內部類=    true
            局部內部類 -> 是否匿名內部類=    false
         */

        System.out.println("---------------------------------------------------------------------------------------");
        Object obj = new Object(){ };
        printInnerClass("匿名內部類", obj.getClass());
        /*
            輸出結果:
            匿名內部類 -> DeclaringClass=    null
            匿名內部類 -> EnclosingClass=    class Test
            匿名內部類 -> EnclosingConstructor=null
            匿名內部類 -> EnclosingMethod=    public void Test.test()
            匿名內部類 -> 是否成員內部類=    false
            匿名內部類 -> 是否局部內部類=    false
            匿名內部類 -> 是否匿名內部類=    true
         */
    }
    
    public static void printInnerClass(String name, Class<?> clazz){
        System.out.println(name + " -> DeclaringClass=\t" + clazz.getDeclaringClass());
        System.out.println(name + " -> EnclosingClass=\t" + clazz.getEnclosingClass());
        System.out.println(name + " -> EnclosingConstructor=" + clazz.getEnclosingConstructor());
        System.out.println(name + " -> EnclosingMethod=\t" + clazz.getEnclosingMethod());
        System.out.println(name + " -> 是否成員內部類=\t" + clazz.isMemberClass());
        System.out.println(name + " -> 是否局部內部類=\t" + clazz.isLocalClass());
        System.out.println(name + " -> 是否匿名內部類=\t" + clazz.isAnonymousClass());
    }
    
    public class InnerClass {
        public class InnerClass2 {
            
        }
    }
    
    public static class StaticInnerClass {
        public static class StaticInnerClass2 {
            
        }
    }
}

 

父子關系

  • getSuperclass():Class<? super T>
    獲取繼承的父類。
  • getGenericSuperclass():Type
  • getAnnotatedSuperclass():AnnotatedType

示例:

public class Test {
    public static void main(String[] params) {
        System.out.println(TestClass.class.getSuperclass());
        System.out.println(TestClass.class.getGenericSuperclass());
        System.out.println(TestClass.class.getAnnotatedSuperclass());
        /*
            運行結果:
            class Test$TestSuperClass
            Test.Test$TestSuperClass<java.lang.Integer>
            sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@a14482
         */
    }
    
    public class TestSuperClass<T> {
        
    }
    
    public class TestClass extends @TestAnnotation TestSuperClass<Integer>{
        
    }
    
    @Target(ElementType.TYPE_USE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TestAnnotation {
        
    }
}
  • getInterfaces():Class<?>[]
    獲取實現的接口集。
  • getGenericInterfaces():Type[]
  • getAnnotatedInterfaces():AnnotatedType[]

示例:

public class Test {
    public static void main(String[] params) {
        System.out.println(Arrays.toString(TestClass.class.getInterfaces()));
        System.out.println(Arrays.toString(TestClass.class.getGenericInterfaces()));
        System.out.println(Arrays.toString(TestClass.class.getAnnotatedInterfaces()));
        /*
            運行結果:
            [interface Test$TestInterface]
            [Test.Test$TestInterface<java.lang.Integer>]
            [sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@a14482]
         */
    }
    
    public interface TestSuperInterface {
        
    }
    
    public interface TestInterface<T> extends TestSuperInterface {
        
    }
    
    public class TestClass implements @TestAnnotation TestInterface<Integer>{
        
    }
    
    @Target(ElementType.TYPE_USE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TestAnnotation {
        
    }
}
  • asSubclass(Class<U>):Class<? extends U>
    把該類型(子類)轉換為目標類型(父類)。
  • isAssignableFrom(Class<?>):boolean
    測試該類型(父類)是否為目標類型(子類)的父類。

用例:

public class Test {
    public static void main(String[] params) {
        test(Object.class);
        System.out.println("---------------------------------");
        test(TestClass.class);
        
        /*
            輸出結果:
            test方法 -> 獲得一個clazz,但不確定它是否為TestSuperClass類型或其子類
            test方法 -> 這個clazz不是TestSuperClass類型或其子類
            ---------------------------------
            test方法 -> 獲得一個clazz,但不確定它是否為TestSuperClass類型或其子類
            test方法 -> 確認這個clazz是TestSuperClass類型或其子類
         */
    }
    
    public static Class<? extends TestSuperClass> test(Class<?> clazz){
        System.out.println("test -> 獲得一個clazz,但不確定它是否為TestSuperClass類型或其子類");
        if(TestSuperClass.class.isAssignableFrom(clazz)){
            System.out.println("test -> 確認這個clazz是TestSuperClass類型或其子類");
            return clazz.asSubclass(TestSuperClass.class);
        }
        System.out.println("test -> 這個clazz不是TestSuperClass類型或其子類");
        return null;
    }
    
    public class TestSuperClass {
        
    }
    
    public class TestClass extends TestSuperClass {
        
    }
}

  

成員類

  • getClasses():Class<?>[]
  • getDeclaredClasses():Class<?>[]

示例:

public class Test {
    public static void main(String[] params) {
        System.out.println(Arrays.toString(TestClass.class.getClasses()));
        System.out.println("---------------------------------");
        System.out.println(Arrays.toString(TestClass.class.getDeclaredClasses()));
        
        /*
            輸出結果:
            [class Test$TestClass$TestMemberClass3, class Test$TestSuperClass$TestSuperMemberClass3]
            ---------------------------------
            [class Test$TestClass$TestMemberClass1, class Test$TestClass$TestMemberClass2, class Test$TestClass$TestMemberClass3]
         */
    }
    
    
    public class TestSuperClass {
        
        private class TestSuperMemberClass1 {
            
        }
        
        protected class TestSuperMemberClass2 {
            
        }
        
        public class TestSuperMemberClass3 {
            
        }
    }
    
    public class TestClass extends TestSuperClass {
        
        private class TestMemberClass1 {
            
        }
        
        protected class TestMemberClass2 {
            
        }
        
        public class TestMemberClass3 {
            
        }
        
    }
}

  

構造器

  • getConstructor(Class<?>...):Constructor<T>
  • getConstructors():Constructor<?>[]
  • getDeclaredConstructor(Class<?>...):Constructor<T>
  • getDeclaredConstructors():Constructor<?>[]

示例:

public class Test {
    public static void main(String[] params) {
        System.out.println(Arrays.toString(TestClass.class.getConstructors()));
        System.out.println(Arrays.toString(TestClass.class.getDeclaredConstructors()));
        
        /*
            運行結果:
            [public Test$TestClass(Test,long)]
            [private Test$TestClass(Test,short), protected Test$TestClass(Test,int), public Test$TestClass(Test,long)]
         */
    }

    public class TestClass {
        private TestClass(short i){
            
        }
        
        protected TestClass(int i){
            
        }
        
        public TestClass(long l){
            
        }
    }
}

  

方法

  • getMethod(String, Class<?>...):Method
  • getMethods():Method[]
  • getDeclaredMethod(String, Class<?>...):Method
  • getDeclaredMethods():Method[]

示例:

public class Test {
    public static void main(String[] params) {
        System.out.println(Arrays.toString(TestClass.class.getMethods()));
        System.out.println("----------------------------------");
        System.out.println(Arrays.toString(TestClass.class.getDeclaredMethods()));
        
        /*
            運行結果:
            [public void Test$TestClass.test(long), public void Test$TestSuperClass.superTest(long), 省略Object的方法……]
            ----------------------------------
            [public void Test$TestClass.test(long), protected void Test$TestClass.test(int), private void Test$TestClass.test(short)]
         */
    }
    
    public class TestSuperClass {
        private void superTest(short i){
            
        }
        
        protected void superTest(int i){
            
        }
        
        public void superTest(long l){
            
        }
    }

    public class TestClass extends TestSuperClass {
        private void test(short i){
            
        }
        
        protected void test(int i){
            
        }
        
        public void test(long l){
            
        }
    }
}

 

字段

  • getField(String):Field
  • getFields():Field[]
  • getDeclaredField(String):Field
  • getDeclaredFields():Field[]

與方法同理……

 

實例

  • newInstance():T
    使用該類的無參構造器創建實例。
  • isInstance(Object):boolean
    測試該對象實例是否為該類的實例。
  • cast(Object):T
    把對象實例轉為該類的實例。
  • getEnumConstants():T[]
    該類為枚舉類型時,可通過此方法獲取其所有枚舉常量。

 

資源

  • getResource(String):URL
    獲取與該類所在目錄下的路徑資源。
  • getResourceAsStream(String):InputStream
    和上同理……

 

其它

  • desiredAssertionStatus():boolean
    測試該類的斷言功能是否已打開。

示例:

test/Test.java

public class Test {
    public static void main(String[] params) {
        Test.class.getClassLoader().setClassAssertionStatus(TestAssert.class.getName(), true);
        TestAssert testAssert2 = new TestAssert();
        testAssert2.test();
        
        /*
            運行結果:
            TestAssert -> 斷言是否已打開=true
            Exception in thread "main" java.lang.AssertionError: 斷言信息!
                at test.TestAssert.test(TestAssert.java:6)
                at test.Test.main(Test.java:10)
         */
    }
}

 test/TestAssert.java

public class TestAssert {
    public void test(){
        System.out.println("TestAssert -> 斷言是否已打開=" + TestAssert.class.desiredAssertionStatus());
        assert false : "斷言信息!";
    }
}

注:打開斷言功能,還可以使用“-ea”參數打開。

  • isSynthetic():boolean
    測試該類是否由編譯器編譯成class文件時所增加的,否則它是由編程人員編寫java源文件時所編寫的。
  • getClassLoader():ClassLoader
    獲取該類被加載時所用的類加載器。
  • getProtectionDomain():ProtectionDomain
    一種權限機制,制定一個代碼源所擁有的權限集合,保護域就是代表一個代碼源的權限集合。
  • getSigners():Object[]
    一種蓋章機制,編寫者編寫完代碼後,由簽名者審核確認無誤後,進行簽名,同一代碼可以由多個簽名者審核後蓋章。

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved