package demo.api;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Person {
public String name;
private int age;
public Person() {//构造函数为什么必须共有
System.out.println("Person空参构造方法执行");
}
Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person含参构造方法执行");
}
String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
int getAge() {
return age;
}
void setAge(int age) {
this.age = age;
}
void show() {
System.out.println("我是" + name + ",今年" + age + "岁");
}
@Override
public String toString() {
return "名字:" + getName() + ",年龄:" + getAge();
}
}
/**
* Declared获取任何修饰符修饰的字段、方法对象,不加的话就是:只能获取public修饰的字段、方法对象
*/
class Class类 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException, IOException {
// getClassObject();//Class对象的获取
// createClassObject("demo.api.Person");//根据Class对象返回的构造方法对象创建指定类对象
// getField("demo.api.Person");//获取Class中的字段
// getMethod("demo.api.Person");//获取指定类中的方法
}
//获取指定类中的方法
private static void getMethod(String className) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class clazz = Class.forName(className);
//打印该类所有方法
Method[] methods = clazz.getDeclaredMethods();
System.out.println(className + "类的所有方法:");
for (Method method : methods) {
System.out.println("\t" + method);
}
//打印该类所有public方法(包括父类方法)
Method[] methods2 = clazz.getMethods();
System.out.println(className + "类的共有方法(包含父类方法):");
for (Method method : methods2) {
System.out.println("\t" + method);
}
//获取指定方法对象,该方法为空参
Method method = clazz.getDeclaredMethod("show", null);
//获取含参构造方法对象
Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class);
//创建Person对象
Object o = constructor.newInstance("阿基米德", 38);//Person p = new Person("阿基米德", 38)
//调用执行show方法(空参)
method.invoke(o, null);//p.show()
//获取指定方法对象,该方法含参
Method method2 = clazz.getDeclaredMethod("setName", String.class);
//使用上面已经创建好的o对象,调用执行setName方法
method2.invoke(o, "米开朗基罗");//p.setName("米开朗基罗")
//调用执行show方法
method.invoke(o, null);//p.show()
}
//获取Class中的字段
private static void getField(String className) throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException {
Class clazz = Class.forName(className);
//Field 字段类
Field fieldName = clazz.getField("name");
System.out.println("字段信息:" + fieldName);
Field fieldAge = clazz.getDeclaredField("age");
System.out.println("Declared字段信息:" + fieldAge);
Field[] fields = clazz.getDeclaredFields();//获取任何修饰符修饰的字段数组
System.out.println(className + "类的所有字段:");
for (Field field : fields) {
System.out.println("\t" + field);
}
Constructor constructor = clazz.getConstructor();
Object o = constructor.newInstance();//创建一个空参Person对象 // Person p = new Person()
fieldAge.setAccessible(true);//暴力访问,取消对私有字段的权限检查。
fieldAge.set(o, 18);//通过age字段对象,设置指定Person对象的age。 // p.age = 18
System.out.println("打印设置后的Person对象:" + o);
Object age = fieldAge.get(o);//获取age的Object形式
System.out.println("指定Person的age内容: " + age);// p.age
}
//根据Class对象返回的构造方法对象创建指定类对象
private static void createClassObject(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//获得Class的一个对象为指定类
Class clazz = Class.forName(className);
//获取指定类的构造方法对象 只能获取public修饰的构造方法
Constructor constructor = clazz.getConstructor();
//构造空参的指定类对象
Object o = constructor.newInstance();
//获取指定类的有参构造函数对象 Declared获取任何修饰符修饰的构造方法对象
Constructor constructor2 = clazz.getDeclaredConstructor(String.class, int.class);
//构造含参的指定类对象
Object o2 = constructor2.newInstance("小明", 18);//通过构造器对象对指定类对象初始化
}
/*
* JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法;
* 对于任意一个对象,都能够调用它的任意一个方法和属性;
* 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
*
* 动态获取类中信息,就是java反射 。
* 可以理解为对类的解剖。
*
* 要想要对字节码文件进行解剖,必须要有字节码文件对象.
* 如何获取字节码文件对象呢?
*/
//Class对象的获取
private static void getClassObject() throws ClassNotFoundException {
Person p = new Person();
Class clazz = p.getClass();//根据类对象获得
Class clazz2 = Person.class;//根据Object类中.class方法获取
System.out.println(clazz == clazz2);
//根据类名获取,若该类不存在,则抛出异常
Class clazz3 = Class.forName("demo.api.Person");
System.out.println(clazz3);
}
}
/**
* 反射的原理
* 首先需要把java文件保存到本地硬盘 .java
* 编译java文件,成.class文件
* 使用jvm,把class文件通过类加载加载到内存中
* 万事万物都是对象,class文件在内存中使用Class类表示
* <p>
* 当使用反射时候,首先需要获取到Class类,得到了这个类之后,就可以得到class文件里面的所有内容
* - 包含属性 构造方法 普通方法
* 属性通过一个类 Filed
* 构造方法通过一个类 Constructor
* 普通方法通过一个类 Method
*/
Class类常用方法
最新推荐文章于 2023-05-27 21:52:05 发布