Java Class类用法

java.lang.Object
   ↳ java.lang.Class <T>

类概述


Java类的内存中表示。此表示作为查询类相关信息的起点,通常称为“反射”的过程。基本上有三种类型的Class 实例:表示实际类和接口的实例,表示基本类型的实例,以及表示数组类的实例。

表示对象类型(类或接口)的类实例

这些代表在类层次结构中找到的普通类或接口。与这些Class实例相关联的名称只是它表示的类或接口的完全限定类名。除了这个人类可读的名字,每个类也通过一个所谓的签名,即字母“L”,其次是类名和分号(“;”)相关联。签名是运行时系统在内部用于标识类(例如在DEX文件中)的标识。

表示原始类型的类

这些表示标准的Java原语类型,因此共享它们的名称(例如对于int基本类型为“int” )。虽然不可能基于这些Class实例创建新实例,但它们仍然可用于提供反射信息以及作为数组类的组件类型。Class每个基本类型都有一个实例,它们的签名是:

  • B表示原byte语类型
  • S表示原short语类型
  • I表示原int语类型
  • J表示原long语类型
  • F表示原float语类型
  • D表示原double语类型
  • C表示原char语类型
  • Z表示原boolean语类型
  • V 表示void函数返回值

表示数组类的类

这些表示Java数组的类。Class 每个数组叶子组件类型和arity(维度数)的组合都有一个这样的实例。在这种情况下,与Class 由一个或多个左方括号(数组中的每个维度一个)组成的名称相关联,后跟表示叶组件类型的类的签名,其可以是对象类型或基本类型。Class表示数组类型的 签名与其名称相同。数组类签名的例子有:

  • [I表示int[]类型
  • [Ljava/lang/String;表示String[]类型
  • [[[C表示char[][][]类型(三维!)

概要


公共方法
<U>  Class  <?延伸U> asSubclass  <U> c)
施放该 Class 表示给定类的子类。
T cast  Object  obj)
将给定对象转换为由此表示的类型 Class
布尔 desiredAssertionStatus ()
返回由此表示的类的断言状态 Class
静态   <?> forName  String  className,boolean shouldInitialize,  ClassLoader  classLoader)
返回表示 Class 具有给定名称的类的对象。
静态   <?> forName  String  className)
返回表示 Class 具有给定名称的类的对象。
<A   extends注释>  A getAnnotation  Class  <A> annotationType)
注解[] getAnnotations ()
返回包含此类的所有注释的数组。
getCanonicalName ()
返回此类的规范名称。
ClassLoader getClassLoader ()
返回用于加载由此表示的类的类加载器 Class
Class []  <?> getClasses ()
返回包含属于此类 Class 的所有公共类和接口的对象的数组
 <?> getComponentType ()
Class 如果此类表示数组类型,则返回表示组件类型的对象。
构造函数  <T> getConstructor  Class ...  <?> parameterTypes)
返回表示 Constructor 与给定参数类型匹配的公共构造函数的对象。
构造函数[]  <?> getConstructors ()
返回一个数组,包含 Constructor所有公共构造函数的 对象 Class
注解[] getDeclaredAnnotations ()
返回在由此表示的类上直接定义的注释 Class
Class []  <?> getDeclaredClasses ()
返回一个数组,该数组包含 Class所有被声明为表示类的成员的类和接口的 对象 Class
构造函数  <T> getDeclaredConstructor  Class ...  <?> parameterTypes)
返回一个 Constructor对象,该 对象表示与由此表示的类声明的给定参数类型匹配的构造函数 Class
构造函数[]  <?> getDeclaredConstructors ()
返回一个数组,包含 Constructor在由此表示的类中声明的所有构造函数的 对象 Class
领域 getDeclaredField  String  name)
返回具有 Field给定名称的字段的 对象,该对象在由此表示的类中声明 Class
领域[] getDeclaredFields ()
返回一个数组,该数组包含由此 Field 表示的类中声明的所有字段的对象 Class
方法 getDeclaredMethod  String  name,  Class ...  <?> parameterTypes)
返回一个 Method对象,该 对象表示与由此表示的类声明的给定名称和参数类型匹配的方法 Class
方法[] getDeclaredMethods ()
返回一个数组,该数组包含由此 Method 表示的类中声明的所有方法的对象 Class
 <?> getDeclaringClass ()
返回宣告 Class 这个 Class
 <?> getEnclosingClass ()
返回封闭 Class 的这个 Class
构造函数  <?> getEnclosingConstructor ()
返回封闭 Constructor Class,如果它是一个匿名或局部/自动类;  否则 null
方法 getEnclosingMethod ()
返回封闭 Method Class,如果它是一个匿名或局部/自动类;  否则 null
T [] getEnumConstants ()
返回 enum 与此相关的常量 Class
领域 getField  String  name)
返回表示 Field 具有给定名称的公共字段的对象。
领域[] getFields ()
返回包含由此 Field表示的类C的所有公共字段的对象 的数组 Class
类型[] getGenericInterfaces ()
返回 Type Class 直接实现的接口的s。
类型 getGenericSuperclass ()
返回表示 Type 此超类的值 class
Class []  <?> getInterfaces ()
返回 Class implements由此表示的类的声明中的接口匹配的对象 数组 Class
方法 getMethod  String  name,  Class ...  <?> parameterTypes)
返回表示 Method 具有给定名称和参数类型的public方法的对象。
方法[] getMethods ()
返回包含由此 Method表示的类C的所有公共方法的对象 的数组 Class
int getModifiers ()
返回一个整数,表示由此表示的类的修饰符 Class
getName ()
返回由此表示的类的名称 Class
getPackage ()
返回由此 Package 表示的类 Class 是一个成员的类 
ProtectionDomain getProtectionDomain ()
返回null。
网址 getResource  String  resourceName)
返回给定资源的URL,如果找不到该资源,则返回null。
InputStream getResourceAsStream  String  resourceName)
返回给定资源的内容的只读流,如果找不到该资源,则返回null。
目的[] getSigners ()
返回null。
getSimpleName ()
返回由 Class 源代码中定义的由此表示的类的简单名称
 <?超级T> getSuperclass ()
返回表示 Class由此表示的类的超类的 对象 Class
synchronized  TypeVariable []  <  Class  <T >> getTypeParameters ()
返回一个数组,该数组包含 TypeVariable由此表示的泛型类声明的类型变量的 对象 Class
布尔 isAnnotation ()
测试这是否 Class 代表注释类。
布尔 isAnnotationPresent  Class  <?   extend Annotation  > annotationType)
指示此元素是否具有带指定注记类型的注释(包括继承注释)。
布尔 isAnonymousClass ()
测试由此表示的类是否 Class 是匿名的。
布尔 isArray ()
测试由此表示的类是否 Class 是数组类。
布尔 isAssignableFrom  Class  <?> c)
测试给定的类类型是否可以转换为由此表示的类 Class
布尔 isEnum ()
测试由此表示的类 Class 是否为  enum
布尔 isInstance  Object  object)
测试给定的对象是否可以转换为由此表示的类 Class
布尔 isInterface ()
测试这是否 Class 代表一个接口。
布尔 isLocalClass ()
测试由此表示的类是否在 Class 本地定义。
布尔 isMemberClass ()
测试由此表示的类是否 Class 是成员类。
布尔 isPrimitive ()
测试这 Class 是否表示原始类型。
布尔 isSynthetic ()
测试这是否 Class 代表合成类型。
T newInstance ()
返回由此表示的类的新实例 Class ,通过调用默认(即零参数)构造函数创建。
toString ()
返回一个包含此对象的简明,可读的描述的字符串。
[扩大]
继承方法
 从类 java.lang.Object
 从接口 java.lang.reflect.AnnotatedElement
 从接口 java.lang.reflect.GenericDeclaration

公共方法


public class <?extends U> asSubclass Class <U> c)
已在 API级别1中添加

施放该Class表示给定类的子类。如果成功,Class则返回; 否则ClassCastException抛出一个。

投掷
ClassCastException 如果这Class不能转换为给定类型。
public T cast Object obj)
已在 API级别1中添加

将给定对象转换为由此表示的类型Class。如果对象是null那么结果也是null

投掷
ClassCastException 如果对象不能转换为给定类型。
public boolean desiredAssertionStatus ()
已在 API级别1中添加

返回由此表示的类的断言状态Class。基于类加载器,软件包或类在运行时默认启用/禁用断言。

public static Class <?> forName String className,boolean shouldInitialize,ClassLoader classLoader)
已在 API级别1中添加

返回表示Class具有给定名称的类的对象。该名称应该是非原语类的名称,如中所述class definition。使用此方法无法找到原始类型; 使用int.classInteger.TYPE代替。

如果类尚未加载,则首先使用给定的类加载器加载。如果类尚未初始化并且shouldInitialize为true,那么将初始化该类。

投掷
ClassNotFoundException 如果无法找到请求的类。
LinkageError 如果在连接期间发生错误
ExceptionInInitializerError 如果在类的静态初始化期间发生异常。
public static Class <?> forName String className)
已在 API级别1中添加

返回表示Class具有给定名称的类的对象。该名称应该是非原语类的名称,如中所述class definition。使用此方法无法找到原始类型; 使用int.classInteger.TYPE代替。

如果类尚未加载,则首先加载和初始化。这通过调用类的类加载器或其父类加载器之一来完成。作为该调用的结果,可能运行静态初始化器。

投掷
ClassNotFoundException 如果无法找到请求的类。
LinkageError 如果在连接期间发生错误
ExceptionInInitializerError 如果在类的静态初始化期间发生异常。
public A getAnnotation Class <A> annotationType)
已在 API级别1中添加

public Annotation [] getAnnotations ()
已在 API级别1中添加

返回包含此类的所有注释的数组。如果没有注释,则返回一个空数组。

返回
  • 此元素的所有注释的数组
也可以看看
public String getCanonicalName ()
已在 API级别1中添加

返回此类的规范名称。如果此类没有Java语言规范中定义的规范名称,则方法返回null

public ClassLoader getClassLoader ()
已在 API级别1中添加

返回用于加载由此表示的类的类加载器Class。实现可以自由地返回null由引导类加载器加载的类。不过,Android引用实现总是返回对实际类加载器的引用。

public Class [] <?> getClasses ()
已在 API级别1中添加

返回包含属于此类Class的所有公共类和接口的对象的数组。这包括从超类和接口继承的公共成员。如果没有这样的类成员或者如果这个对象表示一个原始类型,则返回长度为0的数组。

public Class <?> getComponentType ()
已在 API级别1中添加

Class如果此类表示数组类型,则返回表示组件类型的对象。null如果此类不表示数组类型,则返回。数组类型的组件类型是数组元素的类型。

public Constructor <T> getConstructor Class ... <?> parameterTypes)
API级别9中添加

返回表示Constructor与给定参数类型匹配的公共构造函数的对象。 (Class[]) null相当于空数组。

有关getMethod(String, Class...)搜索顺序的详细信息,请参阅。getDeclaredConstructor(Class...)如果您不想搜索超类,请使用。

投掷
NoSuchMethodException 如果无法找到构造函数。
public Constructor [] <?> getConstructors ()
已在 API级别1中添加

返回一个数组,包含Constructor所有公共构造函数的对象Class。如果没有公共构造函数,或者这Class表示一个数组类,一个原始类型或void,则返回一个空数组。

也可以看看
public Annotation [] getDeclaredAnnotations ()
已在 API级别1中添加

返回在由此表示的类上直接定义的注释Class。继承的注释不包括在结果中。如果根本没有注释,则返回一个空数组。

返回
  • 为此元素声明的注释数组
也可以看看
public Class [] <?> getDeclaredClasses ()
已在 API级别1中添加

返回一个数组,该数组包含Class所有被声明为表示类的成员的类和接口的对象Class。如果没有声明的类或接口,或者这个类表示一个数组类,一个原始类型或void,则返回一个空数组。

public Constructor <T> getDeclaredConstructor Class ... <?> parameterTypes)
API级别9中添加

返回一个Constructor对象,该对象表示与由此表示的类声明的给定参数类型匹配的构造函数Class。 (Class[]) null相当于空数组。

getConstructor(Class...)如果要搜索超类,请使用。

投掷
NoSuchMethodException 如果无法找到请求的构造函数。
public Constructor [] <?> getDeclaredConstructors ()
已在 API级别1中添加

返回一个数组,包含Constructor在由此表示的类中声明的所有构造函数的对象Class。如果没有构造函数,或者这Class表示一个数组类,一个原始类型或void,则返回一个空数组。

也可以看看
public Field getDeclaredField String name)
已在 API级别1中添加

返回具有Field给定名称的字段的对象,该对象在由此表示的类中声明Class

投掷
NoSuchFieldException 如果无法找到请求的字段。
也可以看看
public Field [] getDeclaredFields ()
已在 API级别1中添加

返回一个数组,该数组包含由此Field表示的类中声明的所有字段的对象Class。如果没有字段,或者这Class表示一个数组类,一个原始类型或void,则返回一个空数组。

也可以看看
public Method getDeclaredMethod String name,Class ... <?> parameterTypes)
API级别9中添加

返回一个Method对象,该对象表示与由此表示的类声明的给定名称和参数类型匹配的方法Class。 (Class[]) null相当于空数组。

看看getMethod(String, Class...)你是否要搜索超类。

投掷
NoSuchMethodException 如果找不到请求的方法。
空指针异常 如果namenull
public Method [] getDeclaredMethods ()
已在 API级别1中添加

返回一个数组,该数组包含由此Method表示的类中声明的所有方法的对象Class。如果没有方法,或者这Class表示一个数组类,一个原始类型或void,则返回一个空数组。

也可以看看
public Class <?> getDeclaringClass ()
已在 API级别1中添加

返回宣告Class这个Class。返回 null如果类不是另一个类的成员,或者如果这 Class表示一个数组类,一个基本类型或无效。

public Class <?> getEnclosingClass ()
已在 API级别1中添加

返回封闭Class的这个Class。如果没有封闭类,该方法返回null

public Constructor <?> getEnclosingConstructor ()
已在 API级别1中添加

返回封闭ConstructorClass,如果它是一个匿名或局部/自动类; 否则null

public Method getEnclosingMethod ()
已在 API级别1中添加

返回封闭MethodClass,如果它是一个匿名或局部/自动类; 否则null

public T [] getEnumConstants ()
已在 API级别1中添加

返回enum与此相关的常量Classnull如果这Class不表示enum类型,则返回。

public Field getField String name)
已在 API级别1中添加

返回表示Field具有给定名称的公共字段的对象。此方法首先搜索由此表示的类C Class,然后由C实现的接口和最后C的超类。

投掷
NoSuchFieldException 如果无法找到字段。
也可以看看
public Field [] getFields ()
已在 API级别1中添加

返回包含由此Field表示的类C的所有公共字段的对象的数组Class。字段可以在C,它实现的接口或C的超类中声明。返回数组中的元素没有特定的顺序。

如果没有公共字段或者此类表示数组类,void则返回原始类型或空数组。

也可以看看
public Type [] getGenericInterfaces ()
已在 API级别1中添加

返回TypeClass直接实现的接口的s。如果Class表示一个原始类型,或者void返回一个空数组。

public Type getGenericSuperclass ()
已在 API级别1中添加

返回表示Type此超类的值class

public Class [] <?> getInterfaces ()
已在 API级别1中添加

返回Classimplements由此表示的类的声明中的接口匹配的对象数组Class。数组中元素的顺序与原始类声明中的顺序相同。如果类不实现任何接口,则返回一个空数组。

public Method getMethod String name,Class ... <?> parameterTypes)
API级别9中添加

返回表示Method具有给定名称和参数类型的public方法的对象。 (Class[]) null相当于空数组。

此方法首先搜索由此表示的类C Class,然后搜索C的超类,最后搜索由C及其超类实现的接口。

getDeclaredMethod(String, Class...)如果您不想搜索超类,请使用。

投掷
NoSuchMethodException 如果无法找到该方法。
public Method [] getMethods ()
已在 API级别1中添加

返回包含由此Method表示的类C的所有公共方法的对象的数组Class。方法可以在C,它实现的接口或C的超类中声明。返回数组中的元素没有特定的顺序。

如果没有公共方法,或者这Class表示一个原始类型,或者void返回一个空数组。

也可以看看
public int getModifiers ()
已在 API级别1中添加

返回一个整数,表示由此表示的类的修饰符Class返回的值是由Modifier中的常量定义的位的组合

public String getName ()
已在 API级别1中添加

返回由此表示的类的名称Class有关使用的格式的描述,请参阅类的定义 Class

public Package getPackage ()
已在 API级别1中添加

返回由此Package表示的类Class是一个成员的类 。null如果Package 类的类加载器没有创建对象,则返回

public ProtectionDomain getProtectionDomain ()
已在 API级别1中添加

返回null。

public URL getResource String resourceName)
已在 API级别1中添加

返回给定资源的URL,如果找不到该资源,则返回null。资源名称和URL之间的映射由类的类加载器管理。

也可以看看
public InputStream getResourceAsStream String resourceName)
已在 API级别1中添加

返回给定资源的内容的只读流,如果找不到该资源,则返回null。资源名称和流之间的映射由类的类加载器管理。

也可以看看
public Object [] getSigners ()
已在 API级别1中添加

返回null。(在Android上,a ClassLoader可以从多个dex文件加载类,任何给定dex文件中的所有类都将具有相同的签名者,但不同的dex文件可能有不同的签名者,这不适合ClassLoader基于原始 的模型getSigners

public String getSimpleName ()
已在 API级别1中添加

返回由Class源代码中定义的由此表示的类的简单名称。如果没有名称(即类是匿名的),则返回一个空字符串。如果接收器是数组,则"Integer[]"返回带有方括号的底层类型的名称(例如)。

返回
  • 这个类所表示的类的简单名称Class
public class <?super T> getSuperclass ()
已在 API级别1中添加

返回表示Class由此表示的类的超类的对象Class。如果这Class代表Object类,原始类型,接口或void,则该方法返回null。如果这Class表示数组类,则Object返回该类。

public synchronized TypeVariable [] < Class <T >> getTypeParameters ()
已在 API级别1中添加

返回一个数组,该数组包含TypeVariable由此表示的泛型类声明的类型变量的对象Class。如果类不是通用的,则返回一个空数组。

返回
  • 在声明顺序中声明的类型参数
public boolean isAnnotation ()
已在 API级别1中添加

测试这是否Class代表注释类。

public boolean isAnnotationPresent Class <?extends  Annotation > annotationType)
已在 API级别1中添加

指示此元素是否具有带指定注记类型的注释(包括继承注释)。

参数
annotationType 要搜索的注释的类型
返回
  • true如果注释存在,false否则
public boolean isAnonymousClass ()
已在 API级别1中添加

测试由此表示的类是否Class是匿名的。

public boolean isArray ()
已在 API级别1中添加

测试由此表示的类是否Class是数组类。

public boolean isAssignableFrom Class <?> c)
已在 API级别1中添加

测试给定的类类型是否可以转换为由此表示的类Class。转换可以通过身份转换或扩展引用转换(如果接收方或参数表示原始类型,只有身份转换适用)来完成。

投掷
空指针异常 如果cnull
public boolean isEnum ()
已在 API级别1中添加

测试由此表示的类Class是否为 enum

public boolean isInstance Object object)
已在 API级别1中添加

测试给定的对象是否可以转换为由此表示的类Class。这是instanceof运算符的运行时版本 。

返回
  • true如果object可以转换为由此表示的类型Classfalse如果objectnull或不能铸造。
public boolean isInterface ()
已在 API级别1中添加

测试这是否Class代表一个接口。

public boolean isLocalClass ()
已在 API级别1中添加

测试由此表示的类是否在Class本地定义。

public boolean isMemberClass ()
已在 API级别1中添加

测试由此表示的类是否Class是成员类。

public boolean isPrimitive ()
已在 API级别1中添加

测试这Class是否表示原始类型。

public boolean isSynthetic ()
已在 API级别1中添加

测试这是否Class代表合成类型。

public T newInstance ()
已在 API级别1中添加

返回由此表示的类的新实例Class,通过调用默认(即零参数)构造函数创建。如果没有这样的构造函数,或者如果创建失败(由于缺少可用的内存或者由于构造函数抛出异常),InstantiationException则抛出一个异常。如果默认构造函数存在,但不能从调用此方法的上下文中访问,IllegalAccessException则抛出一个。

投掷
IllegalAccessException 如果默认构造函数不可见。
InstantiationException 如果实例无法创建。
public String toString ()
已在 API级别1中添加

返回一个包含此对象的简明,可读的描述的字符串。鼓励子类覆盖此方法,并提供一个实现,该实现考虑对象的类型和数据。默认实现等效于以下表达式:

   getClass ()。getName ()+ '@' + Integer toHexString hashCode ())    

写一个有用的 toString方法 ,如果你打算实现自己的toString方法。

返回

  • 该对象的可打印表示。

------------------------------------------

参考http://blog.csdn.net/zolalad/article/details/29171541;





Java中Class类与反射机制的用法总结

Java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息,下面我们来了解一下有关java中Class类的相关知识!

首先,Class是一个java类,跟Java API中定义的诸如Thread、Integer类、我们自己定义的类是一样,也继承了Object(Class是Object的直接子类)。总之,必须明确一点,它其实只是个类,只不过名字比较特殊。更进一步说,Class是一个java中的泛型类型。
Java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的(包括类和接口)的信息当一个类或接口被装入的JVM时便会产生一个与之关联的java.lang.Class对象,可以通过这个Class对象对被装入类的详细信息进行访问。(Java中Class对象类的实例对象是两个不同的概念,不能混淆!

Class类的官方定义:public final class Class<T> extends Object implements Serializable, GenericDeclaration, Type, AnnotatedElement

参考手册:http://www.javaweb.cc/JavaAPI1.6/java/lang/Class.html#forName(java.lang.String)

       Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。
       Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。
       虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。
      基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。
      每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
      一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象:
事实上,Class对象就是用来创建类的所有的“普通”对象的。  类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象(恰当地说,是被保存在一个同名的.class文件中)。在运行时,当我们想生成这个类的对象时,运行这个程序的 Java虚拟机(JVM)首先检查这个类的Class对象是否已经加载。如果尚未加载,JVM就会根据类名查找.class文件,并将其载入。  一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有(实例)对象. 示例详见:http://wenku.baidu.com/link?url=U5y6yldkqx1G6Eo90lwCDLyp9t5FBPXQ2E0hCS_1My4Tqtqao_CxlYZW16_n9pUNjr_3vCPAO-XwJb2gIIQcVOEt0KjGc6EtsdWx9XwvLze

一、要想对JVM中Class类封装的信息进行访问,首先要获取对应类的Class对象,而获取“某一个类”所对应的“Class对象可以通过如下三种途径:

1. 通过Object类的getClass方法来获取
java.lang.Object中定义有getClass方法:public final Class getClass()
所有Java对象都具备这个方法
,该方法用于返回调用该方法的对象所属类关联的Class对象,例如:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. Date date1 = new Date();  
  2. Date date2 = new Date();  
  3. Class c1 = date1.getClass();  
  4. Class c2 = date2.getClass();  
  5. System.out.println(c1.getName()); // java.util.Date  
  6. System.out.println(c1 == c2); // true  

上面的代码中,调用Date对象date1的getClass方法将返回用于封装Date类信息的Class对象。

这里调用了Class类的getName方法:public String getName(),这个方法的含义很直观,即返回所封装的类的名称。

需要注意的是 ,代码中的date1和date2的getClass方法返回了相同的Class对象(c1==c2的值为true)。这是因为, 对于相同的类,JVM只会载入一次 ,而与该类对应的Class对象也只会存在一个,无论该类实例化了多少对象。
另外,需要强调的是, 当一个对象被其 父类的引用 或其实现的接口类型的引用 所指向 时,getClass方法返回的是与对象实际所属类关联的Class对象。例如:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. List list = new ArrayList();  
  2. System.out.println(list.getClass().getName()); // java.util.ArrayList  
上面的代码中,语句list.getClass()方法返回的是list所指向对象实际所属类java.util.ArrayList对应的 Class对象而并未java.util.List所对应的Class对象。有些时候可以通过这个方法了解 一个对象的运行时类型 ,例如:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. HashSet set = new HashSet();  
  2. Iterator it = set.iterator();  
  3. System.out.println(it.getClass().getName()); //java.util.HashMap$KeyIterator  
从代码可以看出,HashSet的iterator方法返回的是实现了Iterator接口的HashMap内部类(KeyIterator)对象。
因为抽象类和接口不可能实例化对象,因此不能通过Object的getClass方法获得与抽象类和接口关联的Class对象。
2. 使用.class的方式
使用 类名 加“.class”的方式即会返回与该类对应的Class对象。例如:
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. Class clazz = String.class;  
  2. System.out.println(clazz.getName()); // java.lang.String  
这个方法可以直接获得与指定类关联的Class对象,而并不需要有该类的对象存在。
3. 使用Class.forName方法

Class有一个著名的static方法forName: public static Class forName(String className) throws ClassNotFoundException

该方法可以根据字符串参数所指定的类名获取与该类关联的Class对象。如果该类还没有被装入,该方法会将该类装入JVM。
该方法声明抛出ClassNotFoundException异常。顾名思义,当该方法无法获取需要装入的类时(例如,在当前类路径中不存在这个类),就会抛出这个异常。
例如,如果当前类路径中存在Foo类:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package org.whatisjava.reflect;  
  2. public class Foo {  
  3.     public Foo() {  
  4.         System.out.println("Foo()");  
  5.     }  
  6.     static {  
  7.         System.out.println("Foo is initialized");  
  8.     }  
  9. }  
运行下面的代码:
Class clazz = Class.forName("org.whatisjava.reflect.Foo");
控制台会有如下输出:
Foo is initialized
Class.forName("org.whatisjava.reflect.Foo")首先会将reflection.Foo类装入JVM,并返回与之关联的Class对象。 JVM装入Foo类后对其进行初始化,调用了其static块中的代码 需要注意的是 forName方法的参数是类的完 整限定名(即包含包名)
 区别于前面两种获取Class对象的方法: 使用Class.forName方法所要获取的与之对应的Class对象的类可以通过字符串的方式给定。该方法通常用于在程序运行时根据类名动态的载入该类并获得与之对应的Class对象。
通过上面的文章相信你对java的反射机制有了一定的认识,同时也对java中Class类的用法有了比较清晰的理解,在 我们实际工作的过程中, 我们不断的运用java知识来解决实际生活中的问题的时候我们就能对java反射机制有一个更深入的理解!

二、代码示例

1.ClassTest.java

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * java中Class类的使用 
  3.  */  
  4. import java.io.*;  
  5. import java.lang.reflect.*;  
  6. public class ClassTest1 {  
  7.     public ClassTest1(){  
  8.           
  9.     }  
  10.     public static void main(String[] args) throws Exception{  
  11.         ClassTest1 test=new ClassTest1();  
  12.         ClassTest1 test1=test.getClass().newInstance();  
  13.         //test1=test;  
  14.         test.printMessage();  
  15.         test1.printMessage();  
  16.         System.out.println(test.hashCode());  
  17.         System.out.println(test1.hashCode());  
  18.           
  19.         Method[] method=test1.getClass().getMethods();  
  20.           
  21.         for(Method m :method){  
  22.             System.out.println(m.getDeclaringClass());  
  23.             System.out.println(m.getName());  
  24.         }  
  25.     }  
  26.     public void printMessage(){  
  27.         System.out.println("Created successful!");  
  28.     }  
  29. }  
运行结果:

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. Created successful!  
  2. Created successful!  
  3. 14576877  
  4. 12677476  
  5. class ClassTest1  
  6. printMessage  
  7. class ClassTest1  
  8. main  
  9. class java.lang.Object  
  10. wait  
  11. class java.lang.Object  
  12. wait  
  13. class java.lang.Object  
  14. wait  
  15. class java.lang.Object  
  16. hashCode  
  17. class java.lang.Object  
  18. getClass  
  19. class java.lang.Object  
  20. equals  
  21. class java.lang.Object  
  22. toString  
  23. class java.lang.Object  
  24. notify  
  25. class java.lang.Object  
  26. notifyAll  
2.TestClass.java 

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  
  3.  */  
  4. public class TestClass {  
  5.     public static void main(String[] args)  
  6.     {  
  7.         try {  
  8.             // 测试Class.forName()  
  9.             Class testTypeForName = Class.forName("TestClassType");  
  10.             System.out.println("testForName---" + testTypeForName);  
  11.             // 测试类名.class  
  12.             Class testTypeClass = TestClassType.class;  
  13.             System.out.println("testTypeClass---" + testTypeClass);  
  14.             // 测试Object.getClass()  
  15.             TestClassType testGetClass = new TestClassType();  
  16.             System.out.println("testGetClass---" + testGetClass.getClass());  
  17.         } catch (ClassNotFoundException e) {  
  18.             // TODO Auto-generated catch block  
  19.             e.printStackTrace();  
  20.         }  
  21.     }  
  22. }  
  23.   
  24. class TestClassType {  
  25.     // 构造函数  
  26.     public TestClassType() {  
  27.         System.out.println("----构造函数---");  
  28.     }  
  29.     // 静态的参数初始化  
  30.     static {  
  31.         System.out.println("---静态的参数初始化---");  
  32.     }  
  33.     // 非静态的参数初始化  
  34.     {  
  35.         System.out.println("----非静态的参数初始化---");  
  36.     }  
  37.   
  38. }  
运行结果:

[plain]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. ---静态的参数初始化---  
  2. testForName---class TestClassType  
  3. testTypeClass---class TestClassType  
  4. ----非静态的参数初始化---  
  5. ----构造函数---  
  6. testGetClass---class TestClassType  

分析:根据结果可以发现,三种生成的Class对象一样的,并且三种生成Class对象只打印一次“静态的参数初始化”。 
我们知道,静态的方法属性初始化,是在加载类的时候初始化。而非静态方法属性初始化,是new类实例对象的时候加载。
因此,这段程序说明,三种方式生成Class对象,其实只有一个Class对象。在生成Class对象的时候,首先判断JVM中是否已经加载。

JVM虚拟机为每种类型管理一个独一无二的Class对象,也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值