注解和反射(三)类加载器、动态创建对象
目录
- 注解和反射(三)类加载器、动态创建对象
- 类加载器
- 类加载器的作用
- 获得类的信息
- 动态创建对象
- 对创建的对象进行操作(方法和属性)
- 对方法操作
- Object invoke(Object obj,Object[] args)
- setAccessible(true)
- 代码实例
- 获得类的信息
- 动态的创建对象
- 对对象的方法和属性进行操作
类加载器
类加载器的作用
- 将class文件的字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的java.lang.Class对象,作为方法区中类数据的访问入口
获得类的信息
动态创建对象
- 创建类的对象:调用Class的newInstance()方法
- 类必须有一个无参数的构造器
- 类的构造器的访问权限需要足够
- 有参数的构造器实现创建:
- 通过Class类的getDeclaredConstructor(Class ... parameterTypes)获得类的指定形参类型的构造器
- 向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数
- 通过Constructor实例化对象
对创建的对象进行操作(方法和属性)
关闭程序的安全检测
name.setAccessible(true);//true代表关闭安全检测
对方法操作
- 通过Class类的getDeclaredMethod(String name,Class ... parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型
- 之后使用Object invoke(Object obj,Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息
Object invoke(Object obj,Object[] args)
- Object对应元原方法的返回值,若原方法无返回值,此时返回null
- 若原方法为静态方法,此时形参Object obj可为null
- 若原方法形参列表为空,则Object[] args为null
- 若原方法声明为private,则需要在调用此invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法(关闭安全检测)
setAccessible(true)
- Method和Field、Constructor对象都有setAccessible()方法
- setAccessible作用:启动和禁用访问安全检查的开关
- 参数值为true则指示反射的对象在使用时应该取消Java语言访问检查
- 提高反射效率,如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为true
- 使得原本无法访问的私有成员也可以访问
- 参数值为false则指示反射的对象应该实施Java语言访问检查
代码实例
获得类的信息
public class Test04 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("com.reflect.User2");
System.out.println("-----------获得类1-------------");
//获得类的名字1
System.out.println(c1.getName());//获得包名+类名
System.out.println(c1.getSimpleName());//获得类名
System.out.println("==获得类的属性=============================");
//获得类的属性
Field[] fields1=c1.getFields();//只能找到public属性
Field[] fields2=c1.getDeclaredFields();//找到所有属性
for (Field field : fields2) {
System.out.println(field);
}
System.out.println("==获得指定属性=============================");
//获得指定属性
Field name=c1.getDeclaredField("name");
System.out.println(name);
System.out.println("==获得类的方法=============================");
//获得类的方法
Method[] m2 = c1.getMethods();//获得本类极其父类的全部方法
Method[] m1 = c1.getDeclaredMethods();//获得本类的所有方法
for (Method method : m1) {
System.out.println(method);
}
System.out.println("==获得指定方法=============================");
//获得指定方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);//方法名,属性值
System.out.println(getName);
System.out.println(setName);
System.out.println("==获得构造器=============================");
//获得构造器
Constructor[] d1 = c1.getConstructors();//获得public方法
for (Constructor constructor : d1) {
System.out.println(constructor);
}
Constructor[] d2 = c1.getDeclaredConstructors();//获得全部方法
for (Constructor constructor : d2) {
System.out.println(constructor);
}
System.out.println();
System.out.println("==获得指定的构造器=============================");
//获得指定的构造器
Constructor d3 = c1.getDeclaredConstructor(String.class, int.class, int.class);
System.out.println(d3);
System.out.println("===============================");
//获得类的名字2
System.out.println("-----------获得类2-------------");
Class c2 = Class.forName("com.reflect.User2");
User2 user=new User2();
c2=user.getClass();
System.out.println(c2.getName());//获得包名+类名
System.out.println(c2.getSimpleName());//获得类名
}
}
//实体类
class User2{
private String name;
private int id;
private int age;
public User2(){
}
public User2(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
//输出:
-----------获得类1-------------
com.reflect.User2
User2
==获得类的属性=============================
private java.lang.String com.reflect.User2.name
private int com.reflect.User2.id
private int com.reflect.User2.age
==获得指定属性=============================
private java.lang.String com.reflect.User2.name
==获得类的方法=============================
public java.lang.String com.reflect.User2.toString()
public java.lang.String com.reflect.User2.getName()
public int com.reflect.User2.getId()
public void com.reflect.User2.setName(java.lang.String)
public void com.reflect.User2.setId(int)
public void com.reflect.User2.setAge(int)
public int com.reflect.User2.getAge()
==获得指定方法=============================
public java.lang.String com.reflect.User2.getName()
public void com.reflect.User2.setName(java.lang.String)
==获得构造器=============================
public com.reflect.User2()
public com.reflect.User2(java.lang.String,int,int)
public com.reflect.User2()
public com.reflect.User2(java.lang.String,int,int)
==获得指定的构造器=============================
public com.reflect.User2(java.lang.String,int,int)
===============================
-----------获得类2-------------
com.reflect.User2
User2
动态的创建对象
//动态创建对象,通过反射
public class Test05 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//获得class对象
Class c1 = Class.forName("com.reflect.User3");
//构造一个对象(无参)
User3 user=(User3) c1.newInstance();
System.out.println(user);
//构造一个对象(有参)
//通过构造器创建对象
Constructor c2 = c1.getDeclaredConstructor(String.class, int.class, int.class);
User3 sxp = (User3) c2.newInstance("sxp", 001, 18);
System.out.println(sxp);
}
}
//实体类
class User3{
private String name;
private int id;
private int age;
public User3(){
}
public User3(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
//输出:
User{name='null', id=0, age=0}
User{name='sxp', id=1, age=18}
对对象的方法和属性进行操作
//动态创建对象,通过反射
public class Test06 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获得class对象
Class c1 = Class.forName("com.reflect.User4");
//构造一个对象(无参)
User4 user=(User4) c1.newInstance();
System.out.println("==========通过反射操作方法============");
//通过反射获取一个方法
Method setName = c1.getDeclaredMethod("setName", String.class);
//通过invoke激活方法
//方法.invoke(对象,内容)
setName.invoke(user,"史小鹏");//方法.invoke(对象,内容)
System.out.println(user.getName());
System.out.println("==========通过反射操作属性============");
User4 user4 = (User4) c1.newInstance();
//获取属性值
Field name=c1.getDeclaredField("name");
//不能直接操作私有属性,我们需要关闭程序的安全检测
name.setAccessible(true);
name.set(user4,"张三");//(对象,内容)
System.out.println(user4.getName());
}
}
//实体类
class User4{
private String name;
private int id;
private int age;
public User4(){
}
public User4(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
//输出:
==========通过反射操作方法============
史小鹏
==========通过反射操作属性============
张三