概念
反射:将类的各个组成部分封装成其他对象
java代码在计算机中经历的阶段
- 首先书写Java代码,然后Java代码通过编译称为字节码文件(类名.class)存储在硬盘中(disk)。
- 然后,将硬盘中的字节码加载进内存。
Java中有一个Class类,用来描述字节码文件。类似下面,将成员变量,构造函数和方法分别封装成数组。
public class Class {
public Field [];//成员变量
public Construct [];//构造函数
publid Method [];//方法
}
- 最后,new 一个对象使用。
反射的优点
- 可以在代码执行过程中调用
例如编译器中的方法提示功能。可以将相关的方法放在Method数组中,使用时打印 - 解耦
代码
1、获取Class
2、Field:设置和获得值
3、Construct
4、Method
Person类
public class Person {
public String age;
private String name;
public Person() {
super();
// TODO Auto-generated constructor stub
}
}
1、获取Class
public static Class getPersonClass() {
//1、通过对象.getclass
Person p=new Person();
Class pClass=p.getClass();
//2、通过class
lass pClass=Person.class;
return pClass;
}
2、获取和设置变量的值
Field[] f=pClass.getFields();//将所有的成员变量(public型的)存到Field类的数组中
for(int i=0;i<f.length;i++)
System.out.println(f[i]);//打印所有变量对象
Field age=pClass.getField("age");//将age变量转化成Field类型
System.out.println(age);//打印age
//获取值
Object o=age.get(p);//获得p对象中age的值。 get(Object obj)返回该所表示的字段的值 Field ,指定的对象上。
System.out.println(o);
//设置值
age.set(p, "aa");//将p对象的age的值设置为"aa"
Object o1=age.get(p);
System.out.println(o1);
//getDeclaredFields()将所有的属性名封装成Field对象数组,不论是什么权限
Field[] f2=pClass.getDeclaredFields();
for(int i=0;i<f2.length;i++)
System.out.println(f2[i]);
//getDeclaredField(String 属性名)将某一个属性封装成Field对象
Field f3=pClass.getDeclaredField("name");
System.out.println(f3);
//获取值
System.out.println(f3.get(p));
System.out.println("---------------------------");
//设置私有属性的属性值
f3.setAccessible(true);//暴力反射,会忽略安全修饰符的检查
f3.set(p,"mm");
System.out.printpclass.getConstructors()ln(f3.get(p));
3、获取构造函数Construct
- 获取所有的构造方法 pclass.getConstructors()
public static void getPersonConstruct()
{
Class pclass=getPersonClass();
Constructor [] cons1=pclass.getConstructors();
for(int i=0;i<cons1.length;i++)
{
System.out.println(cons1[i]);
}
}
- 获取特定的构造方法:使用pclass.getConstructor();参数是对应数据类型的class对象,可为空。
public static void getPersonConstruct1() throws Exception, SecurityException
{
Class pclass=getPersonClass();
Constructor cons1=pclass.getConstructor(String.class,String.class);
System.out.println(cons1);
}
- 创建对象:如果是空构造函数。使用class.newInstance()或者cons1.newInstance();否则,使用cons1.newInstance(参数),注意,参数是对象类型的可变参数
public static void getPersonObject() throws Exception, SecurityException
{
Class pclass=getPersonClass();
Constructor cons1=pclass.getConstructor(String.class,String.class);
Object o=cons1.newInstance("张三","十三");
System.out.println(o);
System.out.println("如果构造空构造函数,可以使用class");
System.out.println(pclass.newInstance());
}
获取方法
- 获取所有公有方法:getMethod()和getMethod(“方法名”,数据类型类对象)
public static void getPersonMethod() throws NoSuchMethodException, SecurityException
{
Class pclass=getPersonClass();
//获取所有的公共方法
Method[] methods = pclass.getMethods();
for(int i=0;i<methods.length;i++)
{
System.out.println(methods[i]);
}
System.out.println("----------------------");
//获取指定函数名和参数类型的方法
Method method=pclass.getMethod("eat1",String.class);
System.out.println(method);
//获取全部的方法
//getDeclaredMethods()
//getDeclaringClass()
}
- 获取所有方法:类似Field
- 执行方法:invork(对象,可变参数的实参)
public static void executePersonMethod() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
Class pclass=getPersonClass();
Method method=pclass.getMethod("eat1",String.class);
Person p=new Person();
method.invoke(p, "馒头");
}
获取类名
getName()
来源:CSDN
作者:qq_43573743
链接:https://blog.csdn.net/qq_43573743/article/details/104324868