通过Class类可以获取类和接口。也可以获取到包名、全限定名、类的简称、父类、public修饰的类和修饰符等,以下为示例代码:
import java.lang.reflect.Modifier;
class A {
}
interface B {
}
interface C {
}
public class BaseDemo extends A implements B, C {
// 内部类
public class C {
}
public interface D {
}
public static void main(String[] args) {
// 类可以,接口也可以
Class c = BaseDemo.class;
System.out.println(c);
System.out.println(c.getPackage());// 得到包名
System.out.println(c.getName());// 得到全限定名
System.out.println(c.getSimpleName());// 得到类的简称
/** Class super T> getSuperclass() 此处super表示下限
* 返回表示此 Class所表示的实体(类、接口、基本类型或 void)的超 类的 Class。*/
System.out.println(c.getSuperclass().getSimpleName()); // 得到父类// A, 先获取父类,再获取父类的简称
// 得到接口
System.out.println(c.getInterfaces());
Class>[] arr = c.getInterfaces();
for (Class> cla : arr) {
System.out.println(cla);
}
// 获得public修饰的类
/**Class>[] getClasses()返回一个包含某些 Class对象的数组,这些对象表示属于此 Class对象
* 所表示的类的成员的所有公共类和接口。(如果内部类前面没有加上public的话那么得不到!)*/
Class>[] cl = c.getClasses();
System.out.println(cl.length);// 在内部类没有加上public修饰的时候长度为0,加上就是2(获取的是public/公共的)
for (Class> class1 : cl) {
System.out.println(class1);
}
int i = c.getModifiers();// 获得修饰符
System.out.println(i);// 常量值1表示public
System.out.println(Modifier.toString(i));// 直接打印出public
}
}
结果截图:
总结:在获取的需要有些小细节需要注意一下,我在代码中已经标识了,比如想获取 Class 对象所表示的类的成员的所有公共类和接口。 前提是类的前面有public修饰,如果内部类前面没有加上public的话那么得不到!
常用方法:
Constructor 类用于描述类中的构造方法:
Constructor getConstructor(Class>… parameterTypes)
返回该 Class 对象表示类的指定的 public 构造方法;
Constructor>[] getConstructors()
返回该 Class 对象表示类的所有 public 构造方法;
Constructor getDeclaredConstructor(Class>… parameterTypes)
返回该 Class 对象表示类的指定的构造方法,和访问权限无关;
Constructor>[] getDeclaredConstructors()
返回该 Class 对象表示类的所有构造方法,和访问权限无关;
Method 类用于描述类中的方法:
Method getMethod(String name, Class> … parameterTypes)
返回该 Class 对象表示类和其父类的指定的 public 方法;
Method[] getMethods():
返回该 Class 对象表示类和其父类的所有 public 方法;
Method getDeclaredMethod(String name, Class>… parameterTypes)
返回该 Class 对象表示类的指定的方法。和访问权限无关,但不包括继承的方法;
Method[] getDeclaredMethods(): 获得类所有的方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法;
以下为得到构造器的示例代码:
import java.lang.reflect.Constructor;
class Emp {
private String name;
private int age;
private Emp() {
}
Emp(String name) {
}
public Emp(String name, int age) {
}
}
public class ConstructorDemo {
public static void main(String[] args) throws Exception {
// 得到所有的构造器(先得到类)
Class c = Emp.class;
//getConstructors() 返回一个包含某些 Constructor对象的数组,这些对象反映此Class对象所表示的类的所有公共构造方法。
System.out.println("======前面的修饰符必须是 public,才可以在getConstructors这个方法下获取到=====");
Constructor>[] con = c.getConstructors();
for (Constructor> cons : con) {
System.out.println("c.getConstructors()==" + cons);// 如果上面的某构造器public去掉,则显示不出
}
System.out.println("======getConstructor得到指定的构造器,也是必须public=====");
Constructor> c1 = c.getConstructor(String.class, int.class);//指定形参是String,int
System.out.println("c.getConstructor()=="+c1);
System.out.println("======现在想获得不受public影响的,使用getDeclaredConstructors(),暴力反射=====");
con = c.getDeclaredConstructors();
for (Constructor> cons : con) {
System.out.println("c.getDeclaredConstructors()==" + cons);// 此时不受修饰符的影响
}
}
}
获取方法 Method
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
class AB {
protected String name;
protected String id;
}
@Deprecated
public class MethodDemo extends AB {
void show() {
}
public void say() {
}
private int age;
public char c;
private boolean b;
public static void main(String[] args) throws Exception {
Class c = MethodDemo.class;
// 获取所有的(包含父类的方法)public修饰的方法
Method[] m = c.getMethods();
for (Method method : m) {
System.out.println(method);
}
// 总结:4个方法,获取全部,获取特定;不受修饰符影响的全部,不受修饰符影响的特定;(前两个都还是受限制的)
// 获取指定的方法
Method me = c.getMethod("main", String[].class);
System.out.println("main " + me);
// 访问所有方法,不受访问权限影响
m = c.getDeclaredMethods();
for (Method method : m) {
System.out.println("不受影响的:" + method);
}
me = c.getDeclaredMethod("show");
System.out.println(me);
me = c.getMethod("toString");
System.out.println(me);
// 得到字段
Field[] f = c.getFields();
for (Field field : f) {// 只得到了public的
System.out.println("得到字段" + field);
}
// 特定字段
Field fi = c.getField("c");// ""里面是名称
System.out.println(fi);
// 得到不受限定名限定的全部字段
f = c.getDeclaredFields();
for (Field field : f) {// 得到不受修饰符限定的字段,但是只对当前类有效
System.out.println("全部字段:" + field);
}
// 注释 Annotation
Annotation[] a = c.getAnnotations();
System.out.println(a.length);
for (Annotation annotation : a) {
System.out.println(annotation);
}
// 特定注解
Deprecated d = c.getAnnotation(Deprecated.class);
System.out.println(d);
}
}
获取字段 Field
import java.lang.reflect.Field;
class Stu {
public String name;
public String sex;
public int age;
public Stu(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
}
public class FieldDemo {
public static void main(String[] args) throws Exception {
Stu s = new Stu("刘昭", "男", 12);
Class c = Stu.class;
Field f = c.getField("name");
System.out.println(f.get(s));// //从哪个对象身上取!此时显示刘昭!
// 修改对象的值
/**
* Field f = c.getField("name"); f.set(s,"张飞");
* System.out.println(f.get(s));//从哪个对象身上取!//此时显示张飞
*/
}
}
结果截图:
总结:对于方法,字段,构造方法之类用类获取记住四个:获取全部,获 取特定,暴力获取全部,暴力获取特定!