Java反射 - Java类反射
我们可以使用Java反射来获取关于类的信息,例如作为其包名称,其访问修饰符等。
要获得简单的类名,请使用 Class
中的 getSimpleName()
方法。
String simpleName = c.getSimpleName();
类的修饰符是关键字之前的关键字类在类声明中,如 abstract
, public
。
Class
中的 getModifiers()
方法返回类的所有修饰符。
getModifiers()
方法返回一个整数。我们必须调用 java.lang.reflect.Modifier.toString(int modifiers)
以获得修饰符的文本形式。
要获取超类的名称,请使用 Class
中的 getSuperclass()
方法。
如果对Object类调用getSuperclass()方法,它将返回null,因为它没有超类。
要获取类实现的所有接口的名称,请使用 getInterfaces()
。
Class[] interfaces = c.getInterfaces();
例子
import java.io.Serializable; import java.lang.reflect.Modifier; import java.lang.reflect.TypeVariable; class MyClass<T> implements Cloneable, Serializable { private int id = -1; private String name = "Unknown"; public MyClass(int id, String name) { this.id = id; this.name = name; } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new RuntimeException(e.getMessage()); } } public String toString() { return "MyClass: id=" + this.id + ", name=" + this.name; } } public class Main { public static void main(String[] args) { // Print the class declaration for the Class class String classDesciption = getClassDescription(MyClass.class); System.out.println(classDesciption); } public static String getClassDescription(Class c) { StringBuilder classDesc = new StringBuilder(); int modifierBits = 0; String keyword = ""; if (c.isInterface()) { modifierBits = c.getModifiers() & Modifier.interfaceModifiers(); if (c.isAnnotation()) { keyword = "@interface"; } else { keyword = "interface"; } } else if (c.isEnum()) { modifierBits = c.getModifiers() & Modifier.classModifiers(); keyword = "enum"; } modifierBits = c.getModifiers() & Modifier.classModifiers(); keyword = "class"; String modifiers = Modifier.toString(modifierBits); classDesc.append(modifiers); classDesc.append(" " + keyword); String simpleName = c.getSimpleName(); classDesc.append(" " + simpleName); String genericParms = getGenericTypeParams(c); classDesc.append(genericParms); Class superClass = c.getSuperclass(); if (superClass != null) { String superClassSimpleName = superClass.getSimpleName(); classDesc.append(" extends " + superClassSimpleName); } String interfaces = Main.getClassInterfaces(c); if (interfaces != null) { classDesc.append(" implements " + interfaces); } return classDesc.toString(); } public static String getClassInterfaces(Class c) { Class[] interfaces = c.getInterfaces(); String interfacesList = null; if (interfaces.length > 0) { String[] interfaceNames = new String[interfaces.length]; for (int i = 0; i < interfaces.length; i++) { interfaceNames[i] = interfaces[i].getSimpleName(); } interfacesList = String.join(", ", interfaceNames); } return interfacesList; } public static String getGenericTypeParams(Class c) { StringBuilder sb = new StringBuilder(); TypeVariable<?>[] typeParms = c.getTypeParameters(); if (typeParms.length > 0) { String[] paramNames = new String[typeParms.length]; for (int i = 0; i < typeParms.length; i++) { paramNames[i] = typeParms[i].getTypeName(); } sb.append("<"); String parmsList = String.join(",", paramNames); sb.append(parmsList); sb.append(">"); } return sb.toString(); } }
上面的代码生成以下结果。
class MyClass<T> extends Object implements Cloneable, Serializable
上面的代码生成以下结果。
Class类的实例对象,用于记录类描述信息。
Class类没有公共的构造方法,无法通过new运算符实例化;只能通过对象的getClass方法,或是通过Class.forName(…)来获得实例。
方法 | 目的 |
---|---|
static ClassforName(String className)throws ClassNotFoundException | 使用参数className来指定具体的类,来获得相关的类描述对象,该方法有可能抛出类加载异常(ClassNotFoundException),必须捕捉 |
Class getSuperclass() | 获得当前类描述对象的父类的描述对象 |
String getName() | 返回当前类描述对象的类名称 |
获取Class对象的三种方式:
public class _T11 {
// Class:类描述对象
public static void main(String[] args) {
Class<?> _class;
// ***1*对象.getClass()
String str = "";
_class = str.getClass();
System.out.println(_class + "-----对象名.getClass()");
// ***2*类.class
_class = String.class;
System.out.println(_class + "-----类名.class");
// ***3*Class.forName("")
try {
_class = Class.forName("java.lang.String");
System.out.println(_class + "-----Class.forName(...)");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class java.lang.String-----对象名.getClass()
class java.lang.String-----类名.class
class java.lang.String-----Class.forName(...)
Class类的常用方法:
- getName()
一个Class对象描述了一个特定类的属性,Class类中最常用的方法getName以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。 - newInstance()
Class还有一个有用的方法可以为类创建一个实例,这个方法叫做newInstance()。例如:x.getClass.newInstance(),创建了一个同x一样类型的新实例。newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。 - getClassLoader()
返回该类的类加载器。 - getComponentType()
返回表示数组组件类型的 Class。 - getSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。 - isArray()
判定此 Class 对象是否表示一个数组类。