利用反射创建对象的一些问题

所要构造的类如下所示

 package GetClass;
        
  public class People{
        private  String name;
    public People(){}
    private People(String name){
            this.name =name;
        }
    public String getName() {
            return name; }
    public void setName(String name) {
            this.name = name; }
    
    @Override 
    public String toString() {
            return new String("姓名:"+name); }
    }

平常我们都是用new来构造大概这样

 People people = new People("蜘蛛侠");

但是还有种构造方法称之为反射

try{
           String classname = "GetClass.People";
            Class pClass = Class.forName(classname);
           Constructor c = pClass.getConstructor();
            People p1 = (People) c.newInstance();
           p1.setName("毒液");
      }catch(Exception e){
            e.printStackTrace(); }

这里出了一些小小的问题
1.forname()中的参数只能是public的,而且一个完整的类名需要包括包名。否则会抛出ClassNoFoundException异常。
2.getConstructor()方法只接受默认构造(非无参构造)而如果想传入有参的构造需要调用getDeclaredConstructor()函数。方法如下:

 Constructor c = pClass.getDeclaredConstructor(String.class);
 People p1 = (People) c.newInstance("毒液");

又出现的一点问题该方法是私有无法调用

c.setAccessible(true);

通过该方法可以调取私有,值为 true 反射的对象在使用时取消访问检查。(不是true就能访问false就不能访问,true只是关闭了访问检查的开关)

其实private不代表安全,只是告诉你这个是private的不建议你访问,如果出了事你得自己负责。c.setAccess ible(true)的意思是我觉得你知道你在干什么,那就去做吧。
就像一个女孩穿着超短裙,下面套着安全裤。超短裙就是public是可以给你随便看,但是下面的private就不是一般人看得了的。看了出了事可是要负责的。

运用反射不光可以构造对象,也可以修改对象的字段方法如下:

try{
 Field fd=people.getClass().getDeclaredField("name");
 fd.setAccessible(true);
 fd.set(people,"绿巨人");
 System.out.println(people);
 }catch (Exception e){e.getStackTrace();}

注意:getField 只能获取public的,包括从父类继承来的字段。getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。(获取是获取,就算获取的private也不能直接访问)

当然反射也可以调用方法:

try{//前面的参数是方法名后面的参数是参数类型
   Method md = people.getClass().getMethod("setName", String.class);
   //对people对象调用方法
  md.invoke(people,"金刚狼");
  System.out.println(people);
}catch (Exception e){e.getStackTrace();}

总结一下反射就是通过一个已知的对象(类,普通),调用他们的属性和方法。

猜你喜欢

转载自blog.csdn.net/qq_43313769/article/details/83722609
今日推荐