定义
反射是框架的灵魂,对于任意一个类,能够动态获取信息以及动态调用对象方法的功能,这被称为反射机制。
对象的创建
静态
比如Person p = new Person(),在编译时就已经确定了具体类型,绑定了对象
动态
运行时才会确定具体类型,能够有效降低类之间的耦合度,最大限度发挥java的灵活性
反射机制的实现
在java中,使用一个类,需要把这个类加载到虚拟机(内存)当中,并生成Class对象,这个对象保存了该类的所有信息。反射机制,就是获取这个Class对象。
使用反射的方法
//最常用的方式,多用于读取配置文件
Class p1 = Class.forName("com.person");
//通过类名来获取,但此方法会导入类包,具有依赖性;可用于参数传递
Class p2 = Person.class;
//通过已存在对象创建;可用于获取对象的字节码
Person p = new Person();
p.getClass();
使用反射机制
创建对象
- 创建一个实体类
public class Person
{
private int id;
private String name;
private int age;
public String city;
public Person()
{
}
public Person(int id, String name, int age)
{
this.id = id;
this.name = name;
this.age = age;
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city = city;
}
private void show(String arg)
{
System.out.println("--------------show--->" + arg + "-----------");
}
public void say()
{
System.out.println("-------------------------say-------------------------");
}
}
- 创建对象
//newInstance创建对象
//事实上,它利用实体类的无参构造方法创建对象,如果注释了无参构造,则会创建失败
@Test
public void newTemp1() throws Exception
{
Class temp = Class.forName("com.model.Person");
Object o = temp.newInstance();
System.out.println(o);
}
//getConstructor创建对象
//可以利用有参构造进行对象的创建,但是类型需要对应,否则会报错
@Test
public void newTemp2() throws Exception
{
Class temp = Class.forName("com.model.Person");
//构造器对象,可以传入参数
Constructor cons = temp.getConstructor(int.class, String.class, int.class);
Object o = cons.newInstance(1, "aa", 12);
System.out.println(o);
}
获取构造方法
Class temp = Class.forName("com.model.Person");
//获取所有public构造方法
Constructor[] cons1 = temp.getConstructors();
for (Constructor constructor : cons1)
{
System.out.println("------------cons1" + constructor);
}
//获取所有构造方法(任意类型)
Constructor[] cons2 = temp.getDeclaredConstructors();
for (Constructor constructor : cons2)
{
System.out.println("------------cons2" + constructor);
}
//获取单个public构造方法
Constructor con1 = temp.getConstructor();
System.out.println("------------con1" + con1);
//获取某个构造方法(任意类型)
Constructor con2 = temp.getDeclaredConstructor();
System.out.println("------------con2" + con2);
获取成员变量
Class temp = Class.forName("com.model.Person");
//单个获取
//获得某个public字段
Field city = temp.getField("city");
//获得某个字段(任意类型)
Field name = temp.getDeclaredField("name");
//批量获取
//获得所有public字段
Field[] fields = temp.getFields();
for (Field field : fields)
{
System.out.println(field);
}
//获得所有字段(任意类型)
Field[] declaredFields = temp.getDeclaredFields();
for (Field declaredField : declaredFields)
{
System.out.println(declaredField);
}
给对象赋值
//创建实例
Class temp = Class.forName("com.model.Person");
Object o = temp.newInstance();
//给public属性赋值
Field city = temp.getField("city");
city.set(o,"Toronto");
Person p = (Person) o;
System.out.println(p.getCity());
//给任意属性赋值
Field name = temp.getDeclaredField("name");
//解除私有限定
name.setAccessible(true);
name.set(o, "Sam");
System.out.println(p.getName());
获得方法
Class temp = Class.forName("com.model.Person");
//所有public方法
Method[] methods = temp.getMethods();
for (Method method : methods)
{
System.out.println(method);
}
System.out.println("-------------------------------------------------------");
//获取所有方法(任意类型)
Method[] declaredMethods = temp.getDeclaredMethods();
for (Method declaredMethod : declaredMethods)
{
System.out.println(declaredMethod);
}
调用方法
Class temp = Class.forName("com.model.Person");
Object o = temp.newInstance();
//执行public方法,有参数的方法需要写明参数类型
Method say = temp.getMethod("say");
say.invoke(o);
//执行declared方法,有参数的方法需要写明参数类型
Method show = temp.getDeclaredMethod("show", String.class);
//解除私有限定
show.setAccessible(true);
show.invoke(o, "aaaa");