下面所有案例使用的对象和接口:
public interface TestInterface {
}
@Component
public class TestObject implements TestInterface {
private String name;
private String desc;
public TestObject(){
}
public TestObject(String name){
this.name = name;
}
private TestObject(String name,String desc){
this.desc =desc;
this.name = name;
}
private String testPrivate(String v){
return v;
}
public String testPublic(String v){
return v;
}
}
| 方法 | 返回值 | 说明 |
|---|
| Class.forName("全类名"); | Class | 通过类的全类名,获取类 |
| new Object().getClass(); | Class | 通过对象的getClass方法,获取类 |
| Object.class | Class | 对象的class,获取类 |
| 方法 | 返回值 | 说明 |
|---|
| getName() | String | 获取类的全类名 |
| getSimpleName() | String | 获取类名 |
| getPackage() | Package | 获取类所在的包信息 |
| getSuperclass() | Class | 获取类的父类,单继承 |
| getInterfaces() | Class<?>[] | 获取类实现的接口,多实现 |
| newInstance() | Object | JDK 9+ 已废弃:通过默认构造函数创建类的实例 |
| getAnnotations() | Annotation[] | 获取类上的注解 |
getAnnotation(Class<T> annotationClass) | Annotation | 返回该类上指定类 |
@Test
void test() throws ClassNotFoundException {
// 方式一
Class<?> c1 = Class.forName("top.zouyh.TestObject");
// 方式二
Class<?> c2 = new TestBean().getClass();
// 方式三
Class<?> c3 = TestBean.class;
System.out.println(c1 == c2); // 输出true
System.out.println(c2 == c3); // 输出true
}
通过三种方式获取的Class对象都是相同的,也就是说,一个类只有一个对应的Class对象。
@Test
void test() throws Exception{
Class<?> c1 = Class.forName("top.zouyh.TestObject");
String name = c1.getName();
String simpleName = c1.getSimpleName();
Package aPackage = c1.getPackage();
Class<?> superclass = c1.getSuperclass();
Class<?>[] interfaces = c1.getInterfaces();
System.out.println("name:"+name);
System.out.println("simpleName:"+simpleName);
System.out.println("packageName:"+aPackage.getName());
System.out.println("superclass:"+superclass.getName());
System.out.println("interfaces:"+interfaces.getClass().getName());
}
结果:
name:top.zouyh.TestObject
simpleName:TestObject
packageName:top.zouyh
superclass:java.lang.Object
interfaces:[Ljava.lang.Class;
| 方法 | 返回值 | 说明 |
|---|
getConstructor(Class<?>... parameterTypes) | Constructor | 获得该类中与参数类型匹配的公有的构造方法,不传递参数,获取无参构造 |
| getConstructors() | Constructor<?>[] | 获得该类中所有公有的构造方法 |
getDeclaredConstructor(Class<?>...parameterTypes) | Constructor | 获得该类中与参数类型匹配的构造方法 |
| getDeclaredConstructors() | Constructor<?>[] | 获得该类中所有构造方法 |
| 方法 | 返回值 | 说明 |
|---|
| newInstance() | Object | 创建对象 |
| setAccessible(true) | void | 获取私有的构造方法,需要通过该方法赋权才能使用 |
@Test
void test() throws Exception{
Class<?> c1 = Class.forName("top.zouyh.TestObject");
Constructor<?> g1 = c1.getConstructor();
Constructor<?>[] g2 = c1.getConstructors();
Constructor<?> g3 = c1.getDeclaredConstructor();
Constructor<?>[] g4 = c1.getDeclaredConstructors();
System.out.println("g1:"+g1.newInstance());
System.out.println("g2:"+g2.length);
// 也可以获取共有方法
System.out.println("g3:"+g3.newInstance());
// 多了一个私有的构造方法
System.out.println("g4:"+g4.length);
// 获取带有参数的构造方法
Constructor<?> g5 = c1.getDeclaredConstructor(String.class,String.class);
// 设置公有访问
g5.setAccessible(true);
System.out.println("g5:"+g5.newInstance("name","desc"));
// 会报错,因为getConstructor方法不能直接获取私有的方法
Constructor<?> g6 = c1.getConstructor(String.class,String.class);
System.out.println("g6:"+g6);
}
结果:
g1:top.zouyh.TestObject@4b033eac
g2:2
g3:top.zouyh.TestObject@69c532af
g4:3
g5:top.zouyh.TestObject@45a1d057
java.lang.NoSuchMethodException: top.zouyh.TestObject.<init>(java.lang.String, java.lang.String)
| 方法 | 返回值 | 说明 |
|---|
getMethod(String name, Class<?>... parameterTypes) | Method | 通过方法名称和参数列表类型,获得该类的公有方法,包含继承的 |
| getMethods() | Method[] | 获得该类中所有公有方法,包含继承的 |
getDeclaredMethod(String name, Class<?>... parameterTypes) | Method | 通过方法名称和参数列表类型,获得该类的方法 |
| getDeclaredMethods() | Method[] | 获得该类的所有方法 |
| 方法 | 返回值 | 说明 |
|---|
invoke(Object 实例对象, 参数列表) | Object | 调用方法;静态方法第一个参数传 null;原方法返回 void 时返回 null |
setAccessible(true) | void | 关闭 Java 访问权限检查,使私有方法可被 invoke 调用 |
getReturnType() | Class<?> | 获取方法的返回值类型 |
getParameterTypes() | Class<?>[] | 获取方法的参数类型列表 |
getModifiers() | int | 获取方法的修饰符,配合 Modifier 工具类解析 |
getName() | String | 获取方法名 |
getDeclaringClass() | Class<?> | 获取声明该方法的类 |
getExceptionTypes() | Class<?>[] | 获取方法声明的异常类型 |
getAnnotations() | Annotation[] | 获取方法上的所有注解 |
getAnnotation(Class<T> annotationClass) | T | 返回方法上指定类型的注解,不存在则返回 null |
isVarArgs() | boolean | 是否为可变参数方法 |
isBridge() | boolean | 是否为桥接方法(泛型擦除产生) |
getDefaultValue() | Object | 获取注解方法的默认值 |
@Test
void test() throws Exception {
Class<?> c1 = Class.forName("top.zouyh.TestObject");
Object object = c1.newInstance();
Method[] m1 = c1.getMethods();
Method[] m2 = c1.getDeclaredMethods();
System.out.println("m1:"+m1.length); // 输出:10,自身的1个公有的方法,不包括构造方法,9个父类Object对象的公共方法
System.out.println("m2:"+m2.length); // 输出:2,自身的1个公有,1个私有,不包含构造方法,不包含父类方法
Method m3 = c1.getMethod("testPublic", String.class);
Method m4 = c1.getDeclaredMethod("testPublic", String.class);
System.out.println("m3:"+m3.invoke(object,"公有"));
System.out.println("m4:"+m4.invoke(object,"公有"));
Method m6 = c1.getDeclaredMethod("testPrivate", String.class);
m6.setAccessible(true);
System.out.println("m6:"+m6.invoke(object,"私有"));
// 报错
Method m5 = c1.getMethod("testPrivate", String.class);
m5.setAccessible(true);
System.out.println("m5:"+m5.invoke(object,"私有"));
}
结果:
m1:10
m2:2
m3:公有
m4:公有
m6:私有
java.lang.NoSuchMethodException: top.zouyh.TestObject.testPrivate(java.lang.String)
at java.lang.Class.getMethod(Class.java:1786)
at top.zouyh.TestSpringStartApplicationTests.test16(TestSpringStartApplicationTests.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
| 方法 | 返回值 | 说明 |
|---|
| getField(String name) | Field | 获取该类及其父类指定名称的公有字段。如果字段不存在,则抛出 NoSuchFieldException 异常 |
| getFields() | Field[] | 获取该类及其父类中所有公有字段的数组 |
| getDeclaredField(String name) | Field | 获取该类中指定名称的任意访问权限的字段,包括私有字段,如果字段不存在,则抛出 NoSuchFieldException 异常 |
| getDeclaredFields() | Field[] | 获取该类中所有声明的字段,包括私有字段 |
| 方法 | 返回值 | 说明 |
|---|
| get(Object obj) | Object | 获取字段的值 |
| set(Object obj, Object value) | void | 设置字段值 |
| getName() | String | 获取字段名称 |
| getType() | Class | 获取字段类型 |
| getModifiers() | Int | 获取字段修饰符,Modifier.toString(int modifiers): 将修饰符转换为字符串形式 |
| getAnnotations() | Annotation[] | 获取字段上的注解 |
getAnnotation(Class<T> annotationClass) | Annotation | 返回该字段上指定类型的注解,如果不存在则返回null |
| setAccessible(true) | void | 获取的私有字段,需要通过该方法赋权才能使用 |
@Test
void test() throws Exception {
Class<?> c1 = Class.forName("top.zouyh.TestObject");
TestObject object = (TestObject)c1.newInstance();
Field f1 = c1.getField("desc");
f1.set(object,"666");
Field f2 = c1.getDeclaredField("name");
f2.setAccessible(true);
f2.set(object,"88888");
Field[] f3 = c1.getFields();
Field[] f4 = c1.getDeclaredFields();
System.out.println("f3 size:"+f3.length);
System.out.println("f4 size:"+f4.length);
System.out.println("Object:"+object.desc);
}
结果:
f3 size:1
f4 size:2
Object:666