通过下面三种方法,我们可以获取到类的信息,包括类的名称、修饰符、父类、接口、字段、方法等信息。这些信息可以用于进行反射操作,例如动态创建对象、调用方法、访问字段等。
通过反射可以
1.使用Class.forName()方法
Class.forName()方法可以通过类的全限定名来获取类信息,例如:
Class<?> cls = Class.forName("com.example.MyClass");
这里,com.example.MyClass是类的全限定名,cls是获取到的类信息。需要注意的是,Class.forName()方法需要指定类的全限定名,如果类未被加载或不存在,会抛出ClassNotFoundException异常。
2.使用类字面常量
在Java中,我们可以使用类字面常量来获取类信息,例如:
Class<MyClass> cls = MyClass.class;
这里,MyClass.class是类字面常量,cls是获取到的类信息。需要注意的是,类字面常量只能用于已知类的情况,如果类未被加载或不存在,会抛出NoClassDefFoundError异常。
3.使用对象的getClass()方法
在Java中,我们可以使用对象的getClass()方法来获取类信息,例如:
MyClass obj = new MyClass();
Class<?> cls = obj.getClass();
这里,obj是一个MyClass类型的对象,cls是获取到的类信息。需要注意的是,getClass()方法只能用于已知对象的情况,如果对象为null,会抛出NullPointerException异常。
应用
1.创建一个类,它的name是私有的,怎样把Abc的实例对象设置name为“张三”呢???
可以通过反射。
public class Abc {
private String name;
@Override
public String toString() {
return "Abc{" +
"name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException{
Abc a = new Abc();
//把名字设置成张三
Class cl = Abc.class;
//获取Abc类中名为name的私有属性
Field nameField = cl.getDeclaredField("name");
//设置该属性的可访问性,俗称暴力反射
nameField.setAccessible(true);
nameField.set(a,"张三");
System.out.println(a);
}
2.创建一个类,它的name是私有的,setName()方法是私有的,怎样把Abc的实例对象设置name为“张三”呢???
还是可以通过反射。
public class Abc {
private String name;
private void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Abc{" +
"name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException{
Abc a = new Abc();
Class<Abc> abcClass = Abc.class;
//获取Abc类中名为setName的私有方法
Method setName = abcClass.getDeclaredMethod("setName", String.class);
setName.setAccessible(true);
Object zhangsan = setName.invoke(a, "张三");
System.out.println(a);
}