java反射(一)-java.lang.class方法详解

关于java的java.lang.class类

1.获取class的方式

类名直接获取:

Class cstr = String.class;

调用class的静态方法获取:

Class cstr = Class.forName("java.lang.String");

通过实例对象获得:

String str = "abc";
Class cstr = str.getClass();

Class类有如下方法

静态方法
方法名参数返回类型说明
forName
String className
Class<?>

接收className全称,使用类加载器加载class,并返回class对象

例如:

Class.forName("java.lang.String")

forName
String name, boolean initialize,ClassLoader loader
Class<?>
使用指定类加载器加载class文件
public方法
方法名参数返回类型说明
获得ClassName相关方法
toString
 
String

例如:String

class java.lang.String

toGenericString
 
String

声明全称

public final class java.lang.String

getName
 
String

获得class的名字

例如: int->int

String->java.lang.String

getSimpleName
 
String

获得class的simple name

例如:java.lang.String->String

getComponentType
 
Class<?>

获得组成类型 针对数组而言 非数组为null 数组为基本类型

例如:

int[] -> int

String->null

getTypeName
 
String
如果是数组 getComponentType加上[],否则 getName()
getCanonicalName
 
String

 返回基础类的规范名称,如果没有则返回null

获得相关属性和对象的方法
newInstance
 T

获得实例对象

String对象的newInstance()值和该String相同

getClassLoader
 
ClassLoader

获得类加载器,只能获得AppClassLoader即应用类加载器,

父级的扩展类加载器和启动类加载器都返回null,不可获得

例如:Objcet.class.getClassLoader() ->  null

getTypeParameters
 
TypeVariable<Class<T>>[]

获得class的泛型参数变量

例如:List<E> 返回E

注: ArrayList<String> 返回 E

class声明的泛型参数,

创建时指定的会被类型擦除

getSuperclass
 
Class<? super T>

获得父类,没有继承的class,父类为

java.lang.Object

getGenericSuperclass
 
Type
获得父类的类型
getPackage
 
Package
获得class的package
getInterfaces
 
Class<?>[]
获得该class实现的所有接口
getGenericInterfaces
 
Type[]
获得class 实现的interface的Type
getModifiers
 
int

获得一个描述修饰符的int值,利用modifier类去解析该int值,得到该class满足哪些修饰符

getSigners
 
Object[]
此方法返回这个类的签名,或者为null,如果没有签名,如果这个对象表示一个基本类型或void,则返回null
class相关
getClasses
 
Class<?>[]
获得class里的所有public类
getDeclaredClasses
 
Class<?>[]
所有定义的类
getDeclaringClass
 
Class<?>

返回表示在它被声明的类的Class对象,如果此Class对象所表示的类或接口是另一个类成员。

如果这个类或接口不属于任何其他类成员此方法返回null。如果此Class对象表示一个数组类,基本类型或void,则此方法返回null。

getEnclosingClass
 
Class<?>
方法返回直接封闭类的底层类。如果这个类是一个顶级类此方法返回null
Field相关
getFields
 
Field[]
获得public的字段
getField
String name
Field
根据name获得public的字段
getDeclaredFields
 
Field[]
获得所有声明的字段
getDeclaredField
String name
Field
根据name获得声明的字段
Method相关
getMethods
 
Method[]
获得所有public方法
getMethod
String name, Class<?>... parameterTypes
Method
根据name和参数类型,指定获得public方法
getDeclaredMethods
 
Method[]
获得声明的方法
getDeclaredMethod
String name, Class<?>... parameterTypes
Method
根据name和参数类型,指定获得声明的方法
getEnclosingMethod
 
Method
如果一个class表示在方法中的一个本地或匿名class, 那么通过java.lang.Class.getEnclosingMethod()方法将返回的底层类的立即封闭方法
构造函数相关
getConstructors
 
Constructor<?>[]
获得public的构造函数
getConstructor
Class<?>... parameterTypes
Constructor<T>
根据参数类型,获得public的构造函数
getDeclaredConstructors
 
Constructor<?>[]
获得所有声明的构造函数
getDeclaredConstructor
Class<?>... parameterTypes
Constructor<T>
根据参数类型,指定获得声明的构造函数
getEnclosingConstructor
 
Constructor<?>
 
枚举Enum相关
getEnumConstants
 
T[]
获得枚举常量
Annotation 注解相关
getAnnotations
 
Annotation[]
获得所有public的注解
getAnnotation
Class<A> annotationClass
<A extends Annotation> A
根据指定注解class,获得所有public的注解对象
getAnnotationsByType
Class<A> annotationClass
<A extends Annotation> A[]
根据类型获得注解
getDeclaredAnnotation
Class<A> annotationClass
<A extends Annotation> A
获得指定注解声明的对象
getDeclaredAnnotationsByType
Class<A> annotationClass
<A extends Annotation> A[]
根据类型获得声明的所有注解
getDeclaredAnnotations
 
Annotation[]
获得声明的所有注解
getAnnotatedSuperclass
 
AnnotatedType
获得注解的父类的Type
getAnnotatedInterfaces
 
AnnotatedType[]
获得注解接口
其他属性
getResourceAsStream
String name
InputStream
根据名称获得资源的inputstream
getResource
String name
java.net.URL
根据名称获得资源的url
getProtectionDomain
 
java.security.ProtectionDomain
 
cast
Object obj
T
类型转换
asSubclass
Class<U> clazz
<U> Class<? extends U>
 
和其他对象的判断
isInstance
Object obj
boolean

判断是否是这个class的实例

注: 子类是父类的实例

isAssignableFrom
Class<?> cls
boolean
判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回 true;否则返回 false
class类型和关键字的判断
isInterface
 
boolean
是否是接口
isArray
 
boolean
是否是数组
isPrimitive
 
boolean

基本类型 

void,boolean,byte,char,short,int,long,float,double

封装类型不是基本类型

isAnnotation
 
boolean

是否是注解类型

注解类型为 @Interface ,因此 isInterface也返回true

isSynthetic
 
boolean

是否是合成类synthetic

即静态内部类,由jvm编译成的类

isAnonymousClass
 
boolean
是否是匿名类
isLocalClass
 
boolean
是否是本地类
isMemberClass
 
boolean
是否是成员类
desiredAssertionStatus
 
boolean
 
isEnum
 
boolean
是否是枚举class
isAnnotationPresent
Class<? extends Annotation> annotationClass
boolean
 

 

Demo

static方法

forName

    @Test
    public void classStaticMethodDemo(){
        try {
           Class clazz =  Class.forName("java.lang.String");
           System.out.println(clazz.getName());

           ClassLoader classLoader = this.getClass().getClassLoader();
           //指定类加载器加载class文件,完全不同的类加载器加载的同一个class不同
            Class clazz2 = Class.forName("com.hjh.java.reflect.ClassTest",true,classLoader);
            System.out.println(clazz2.getName());
            //应用类加载器,用于加载用户自己的类
            System.out.println(classLoader.getClass().getName());
            //扩展类加载器,用于加载%JAVA_HOME%/jre/lib/ext java.ext.dirs指定的类
            System.out.println(classLoader.getParent().getClass().getName());
            //启动类加载器,因为是用c++写的,所以这里报错,getParent()返回为null 用于加载Object,String等jre的运行java类
            System.out.println(classLoader.getParent().getParent().getClass().getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

结果:

java.lang.String
com.hjh.java.reflect.ClassTest
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader

java.lang.NullPointerException

public方法

获得className相关的方法

    @Test
    public void classNameMethodDemo(){
        Class cstr = String.class;
        Class cclose = Closeable.class;
        int[] is = new int[100];
        Class array =  is.getClass();
        HashMap<String,String> map = new HashMap<>();
        Class cmap = map.getClass();

        /**
         * getName 获得class的Name
         */
        System.out.println("------- getName -----------");
        //全称,带package名
        System.out.println(cstr.getName());//java.lang.String
        System.out.println(cclose.getName());//java.io.Closeable
        //基本类型数组比较特别
        System.out.println(array.getName());//[I
        System.out.println(cmap.getName());//java.util.HashMap


        /**
         * getSimpleName 获得简单ClassName,不带package的名称
         */

        System.out.println("------- getSimpleName -----------");

        //直接类名
        System.out.println(cstr.getSimpleName());//String
        System.out.println(cclose.getSimpleName());//Closeable
        System.out.println(array.getSimpleName());//int[]
        System.out.println(cmap.getSimpleName());//HashMap

        /**
         *toGenericString 生成一个全称的字符串,包括修饰符
         */
        System.out.println("-------- toGenericString ---------");
        // 定义语句
        System.out.println(cstr.toGenericString());//public final class java.lang.String
        System.out.println(cclose.toGenericString());//public abstract interface java.io.Closeable
        System.out.println(array.toGenericString());//public abstract final class [I
        System.out.println(cmap.toGenericString());//public class java.util.HashMap<K,V>

        /**
         * toString()方法
         * 分为 class 和 interface 两种开头
         */
        System.out.println("-------- toString ----------");

        System.out.println(cstr.toString());//class java.lang.String
        System.out.println(cclose.toString());//interface java.io.Closeable
        System.out.println(array.toString());//class [I
        System.out.println(cmap.toString());//class java.util.HashMap

        /**
         * getComponentType
         * 获得组成类型 针对数组而言
         * 非数组为null 数组为基本类型
         */
        System.out.println("--------- getComponentType ---------");
        System.out.println(cstr.getComponentType());//class java.lang.String
        System.out.println(cclose.getComponentType());//interface java.io.Closeable
        System.out.println(array.getComponentType());//int[]
        System.out.println(cmap.getComponentType());//java.util.HashMap

        /**
         * getTypeName 获得TypeName
         * 如果是数组 getComponentType加上[],
         * 否则 getName()
         */
        System.out.println("-------- getTypeName ----------");
        System.out.println(cstr.getTypeName());//class java.lang.String
        System.out.println(cclose.getTypeName());//interface java.io.Closeable
        System.out.println(array.getTypeName());//int[]
        System.out.println(cmap.getTypeName());//java.util.HashMap

        /**
         * getCanonicalName 返回基础类的规范名称
         * 如果没有则返回null
         */
        System.out.println("-------- getCanonicalName ----------");
        System.out.println(cstr.getCanonicalName());//class java.lang.String
        System.out.println(cclose.getCanonicalName());//interface java.io.Closeable
        System.out.println(array.getCanonicalName());//int[]
        System.out.println(cmap.getCanonicalName());//java.util.HashMap

    }

获得相关属性的方法

    @Test
    public void classPropertiesDemo(){
        int[] arr = new int[10];
        HashMap<String,String> map = new HashMap<>();
        String str = new String("abc");

        Class carr = arr.getClass();
        Class cmap = map.getClass();
        Class cstr = str.getClass();

        /**
         * newInstance
         * 根据class获得实例,无法反射数组
         * 泛型对象只能反射类型擦除后的对象指针
         */
        System.out.println("------- newInstance -----------");
        try {
            //无法反射数组 抛出 InstantiationException
//            int [] arr2 = (int[])carr.newInstance();
            // 可以反射泛型,因为类型擦除 这里转为HashMap和任意HashMap<K,V>都可以
            HashMap map2 = (HashMap<String,Integer>) cmap.newInstance();
            System.out.println(map2.size());//0

            //可以反射string类 但是值和原值相同
            String str2 = (String)cstr.newInstance();
            System.out.println(str);// abc

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        /**
         * getClassLoader
         * 获得该class的类加载器
         */
        System.out.println("------- getClassLoader -----------");
        // 启动类加载器是 c++实现,所以返回null
        System.out.println(String.class.getClassLoader());//null
        // 应用类加载器是java实现,返回某个实例
        System.out.println(this.getClass().getClassLoader());//sun.misc.Launcher$AppClassLoader@18b4aac2

        /**
         * getTypeParameters
         * 获得泛型对象的泛型名称,无法获得泛型的具体类型
         * 补充一种可以获得泛型具体实例的办法
         * @see GenericSuperclassTest
         */
        System.out.println("------- getTypeParameters -----------");
        // 数组没有泛型
        printArray(carr.getTypeParameters());
        //输出hashmap的泛型名称K,V,但是不能获得具体是String,还是Objcet
        printArray( cmap.getTypeParameters());//K V
        // 字符串没有泛型
        printArray(cstr.getTypeParameters());

        /**
         * getSuperclass
         * 获得父类的class
         */
        System.out.println("------- getSuperclass -----------");
        System.out.println(carr.getSuperclass().getName());//java.lang.Object
        System.out.println(cmap.getSuperclass().getName());//java.util.AbstractMap
        System.out.println(cstr.getSuperclass().getName());//java.lang.Object

        /**
         * getGenericSuperclass 获得父类的类型
         * 补充一种可以获得泛型具体实例的办法
         * @see GenericSuperclassTest
         */
        System.out.println("------- getGenericSuperclass -----------");
        System.out.println(carr.getGenericSuperclass().getTypeName());//java.lang.Object
        System.out.println(cmap.getGenericSuperclass().getTypeName());//java.util.AbstractMap<K, V>
        System.out.println(cstr.getGenericSuperclass().getTypeName());//java.lang.Object

        /**
         * getPackage
         * 获得class的package
         */
        System.out.println("------- getPackage -----------");
        //基本类型数组没有package的概念,所以为null
        System.out.println(carr.getPackage());
        System.out.println(cmap.getPackage().getName());//java.util
        System.out.println(cstr.getPackage().getName());//java.lang

        /**
         * getInterfaces
         * 获得class 实现的interface的class
         */
        System.out.println("------- getInterfaces -----------");
        printArray(carr.getInterfaces());//interface java.lang.Cloneable,interface java.io.Serializable
        printArray(cmap.getInterfaces());//interface java.util.Map,interface java.lang.Cloneable,interface java.io.Serializable,
        printArray(cstr.getInterfaces());//interface java.io.Serializable,interface java.lang.Comparable,interface java.lang.CharSequence,

        /**
         * getGenericInterfaces
         * 获得class 实现的interface的Type
         */
        System.out.println("------- getGenericInterfaces -----------");
        printArray(carr.getGenericInterfaces());//interface java.lang.Cloneable,interface java.io.Serializable,
        printArray(cmap.getGenericInterfaces());//java.util.Map<K, V>,interface java.lang.Cloneable,interface java.io.Serializable,
        printArray(cstr.getGenericInterfaces());//interface java.io.Serializable,java.lang.Comparable<java.lang.String>,interface java.lang.CharSequence,

        /**
         * getModifiers
         * 获得一个描述修饰符的int值,利用modifier类去解析该int值,得到该class满足哪些修饰符
         */
        System.out.println("------- getModifiers -----------");
        int marr = carr.getModifiers();
        int mmap = cmap.getModifiers();
        int mstr = cstr.getModifiers();
        System.out.println(marr);//1041
        System.out.println(mmap);//1
        System.out.println(mstr);//17

        Modifier modifier = new Modifier();

        modifier.isPublic(marr);
        modifier.isPrivate(marr);
        modifier.isProtected(marr);

        /**
         * getSigners
         * 得到这个类的签名
         */
        //这个为null
        printArray(carr.getSigners());//null
        printArray(cmap.getSigners());//null
        printArray(cstr.getSigners());//null

    }

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值