您的位置:首页 > 其它

利用反射创建对象

2018-04-03 11:52 183 查看
创建对象:
1、使用 Class 对象的 newInstance()方法创建该 Class 对象的实例,此时该 Class 对象必
须要有无参数的构造方法。
2、使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 的 newInstance()
方法创建对象类的实例,此时可以选择使用某个构造方法。如果这个构造方法被私有化起来,
那么必须先申请访问,将可以访问设置为 true;
Eg:
最简单的:
package com.lx;
class User{
/*private User(){//将默认的构造方法私有化的话就不可以再创建对象,两种方
法都是这样
}*/
public String toString() {
return "User对象创建成功!";
}
}
public class NewInstanceDemo6 {
public static void main(String[] args) throws Exception {
//传统方式创建对象
System.out.println(new User());
//使用反射的方式
Class<User> c = User.class;
User u = c.newInstance();(直接newInstance的话必须保证默认的构
造方法正常存在,也就是没有被私有化!这是前提条件)
System.out.println(u);
}
}
复杂点的:更强大的第二种:
使用指定构造方法来创建对象:
获取该类的 Class 对象。
利用 Class 对象的 getConstructor()方法来获取指定的构造方法。
调用 Constructor 的 newInstance()方法创建对象。
AccessibleObject 对象的 setAccessible(boolean flag)方法,当 flag 为 true 的时候,就会忽略访问
权限(可访问私有的成员)。
其子类有 Field, Method, Constructor;
若要访问对象 private 的成员?
在调用之前使用 setAccessible(true),
Xxx x = getDeclaredXxxx();//才能得到私有的类字段.
总结步骤:
1. 获取该类的 Class 对象。
2. 利用 Class 对象的 getConstructor()方法来获取指定的构造方法。
3. 申请访问(设置为可访问)
4. 调用 Constructor(构造方法)的 newInstance()方法创建对象。
例子
package com.lx;
import java.lang.reflect.Constructor;
class Per{
private String name;
private int age;
private Per(){
}
private Per(String name){
}
public String toString() {
return "对象!!!";
}
}
public class NewInstanceDemo7 {
public static void main(String[] args) throws Exception {
Class<Per> c = Per.class;
//System.out.println(c.newInstance());;//证明利用无参的可以
////先获得需要被调用的构造器(private 修饰的构造方法)
Constructor<Per> con = c.getDeclaredConstructor();//调用默认
的,什么都不要写
System.out.println(con);//private com.lx.Per()
/*con = c.getDeclaredConstructor(String.class);获取指定的构造
方法
System.out.println(con);//private 
com.lx.Per(java.lang.String)*/
//现在只需要执行这个构造器,
/**
* T newInstance(Object... initargs) 
使用此 Constructor 对象表示的构造方法来创建该构造方法的声明
类的新实例,并用指定的初始化参数初始化该实例。
*/
//私有的成员是受保护的,不能直接访问
//若要访问私有的成员,得先申请一下
con.setAccessible(true);//允许访问
Per p = con.newInstance();//成功,通过私有的受保护的构造方法创建了
对象
System.out.println("无参构造方法"+p);
con = c.getDeclaredConstructor(String.class);
System.out.println(con);//private 
com.lx.Per(java.lang.String)
con.setAccessible(true);//允许访问
p = con.newInstance("lx");//成功,通过私有的受保护的构造方法
创建了对象
System.out.println("String构造方法"+p);
}
}
备注:对于此时的话,单例模式就不再安全了!反射可破之!!
验证:对于枚举而言,反射依然没有办法重新创建对象
对于枚举,安全!
package com.lx;
import java.lang.reflect.Constructor;
enum Color{
RED,BLUE,GREEN;
private Color(){
}
}
public class EnumDemo8 {
public static void main(String[] args) throws Exception {
Class<Color> c = Color.class;
Constructor<Color> con = c.getDeclaredConstructor();//(错误
在这一行发生,就是说对枚举而言这种方法连构造器都获得不了,)编译可以通过,但是运
行就通不过了!
Color co = (Color) con.newInstance();
System.out.println(co);//失败,证明对枚举而言不行,所以枚举的单例模
式更加安全
System.out.println(c.isEnum());//true是枚举
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  反射