• 反射——类(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 + " -> 是否数组=	" + clazz.isArray());
            System.out.println(name + " -> 是否接口=	" + clazz.isInterface());
            System.out.println(name + " -> 是否注解=	" + clazz.isAnnotation());
            System.out.println(name + " -> 是否枚举=	" + 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=	" + clazz.getDeclaringClass());
            System.out.println(name + " -> EnclosingClass=	" + clazz.getEnclosingClass());
            System.out.println(name + " -> EnclosingConstructor=" + clazz.getEnclosingConstructor());
            System.out.println(name + " -> EnclosingMethod=	" + clazz.getEnclosingMethod());
            System.out.println(name + " -> 是否成员内部类=	" + clazz.isMemberClass());
            System.out.println(name + " -> 是否局部内部类=	" + clazz.isLocalClass());
            System.out.println(name + " -> 是否匿名内部类=	" + 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[]
      一种盖章机制,编写者编写完代码后,由签名者审核确认无误后,进行签名,同一代码可以由多个签名者审核后盖章。

      

  • 相关阅读:
    Redis详解
    Linux常用命令
    sqlserver 游标写法
    Flask总结
    HTTPS协议
    Django REST framework 简介
    Cookie和session
    利用rest-framework编写逻辑关系
    vuex
    jQuery和Bootstrap的优点
  • 原文地址:https://www.cnblogs.com/hvicen/p/6261878.html
Copyright © 2020-2023  润新知