类的调用(调用类中成员)、暴力访问

public class Person {

private String name;
private int age;
public static final double PI=3.14;
public double value;

public Person() {
    name="匿名";
}
public Person(String name, int age) {
    this.name = name;
    this.age = age;
}
private Person(String name) {
    this.name = name;
}

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;
}

@Override
public String toString() {
    System.out.println("111111111");
    return name + ", " + age;
}

public int sum( int m, int n){
    int s=0;
    for(int i=m;i<=n;i++){
        s +=i;
    }
    return s;
}

public static void aa(){
    System.out.println(PI);
}

private int sum(int n){
    return n+100;
}

}

public class ReflectOperateObj {
private static final String className=”cn.hncu.reflect.Person”;

使用构造器新建对象


最核心的代码: Constructor con= c.getConstructor(paramTypes); con.newInstance(args);
@Test
public void operateConstructor(){
try {
Class c = Class.forName(className);

1 .调用空参构造方法

//简便方式new一个空参对象
           Object obj = c.newInstance();//选用空参构造方法新建一个对象
           System.out.println(obj);
//常规方式:先拿到对应构造器的对象,然后利用该构造器对象(代表那个构造函数)调用newInstance()方法造出对象
          Constructor con = c.getConstructor(null);//获取空参构造方法
          Object obj2 = con.newInstance(null);
          System.out.println(obj2); 
2 .调用非空参构造方法

//只能常规方法:必须先通过形参获得对应的构造方法,然后通过实参调用该构造方法
          //2.1获取指定的构造器--通过形参
          Class parameterTypes[] = new Class[2];
          parameterTypes[0] = String.class;
          parameterTypes[1] = Integer.TYPE;
          Constructor con2= c.getConstructor(parameterTypes);
          //2.2调用该构造器来new对象---通过实参
          Object params[] = new Object[2];//调用构造方法是要传入的参数
          params[0]=new String("Jack");
          params[1]=new Integer(24);
          Object obj3 = con2.newInstance(params);
          System.out.println(obj3);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

调用普通方法


最核心的代码: Method m = c.getMethod(name,paramTypes); m.invoke(obj,args);**
@Test
public void callMethod(){
try {
Class c = Class.forName(className);

1 .调用空参方法

Person p = new Person(); p.toString();

           //1.1先获得该Method对象---通过形参
           Method m = c.getMethod("toString", null);
           //1.2再让该Method对象执行---通过实参
           Object p = c.newInstance();
           Object returnValue = m.invoke(p, null);//执行方法---p.toString()
           System.out.println(">>>> "+ returnValue);
2.调用非空参方法

 //2.1先获得该Method对象---通过形参
           Class parameterTypes[] = new Class[2];
           parameterTypes[0] = int.class;//参数类型为int--OK
           //parameterTypes[0] = Integer.TYPE;//参数类型为int--OK
           //下句小细节:因为这是一个纯粹的类,里面没有拆箱功能,无法当作int类型。但如果sum()中的第一个参数就是Integer类型,那么下句OK
           //parameterTypes[0] = Integer.class;//参数类型为int--ERROR

           parameterTypes[1] = int.class;
           Method m2 = c.getDeclaredMethod("sum", parameterTypes);

           //2.2再让该Method对象执行---通过实参  p.sum(100,200);
           Object p2 = c.newInstance();
           Object args[] = new Object[2];
           args[0] = 1;
           args[1] =100;
           Object res = m2.invoke(p2, args);
           System.out.println("res: " + res);
3.调用静态方法

           Method m3 = c.getMethod("aa", null);
           m3.invoke(null, null);//静态方法的调用不需要对象,类名可以省略,所以传入null就行。至于方法的实参,同前
   } catch (Exception e) {
       e.printStackTrace();
   }

}

访问属性(成员变量、类变量)


—-最核心代码: Field fld = c.getFild(name); 专用setter-getter方法:fld.setDouble(p,value);fld.getDouble(p) 通用setter-getter方法:fld.set(p,value);fld.get(p)
//Person p = new Person(); p.value=11.22;**
@Test

  public void AccessField(){
       try {
           Class c = Class.forName(className);
           //获取Field对象
           Field fld = c.getField("value");
           //操纵该Field对象,以进行读写属性值
           Object p = c.newInstance();
           //通用的setter-getter方法
           //fld.set(p,11.22);//设置值
           //double x = (Double)fld.get(p) + 100;//获取值
           //专用的setter-getter方法
           fld.setDouble(p, 22.33);
           double x = fld.getDouble(p) + 100;//获取值
           System.out.println(x);
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

暴力访问

**---访问类中的私有成员(构造器、普通方法、属性)---这三者的公共父类AccessibleObject中的方法setAccessible(boolean flag)可以打开私有访问权限**

//强行访问私有方法: private int sum(int n)
@Test

   public void AccessBlood(){
       try {
           Class c = Class.forName(className);
           Method m = c.getDeclaredMethod("sum", int.class);
           m.setAccessible(true);//暴力访问,打开访问权限。---其实是调用父类AccessibleObject中的该方法
           Object res = m.invoke(c.newInstance(), 100);
           System.out.println(res);

       } catch (Exception e) {
           e.printStackTrace();
       }
   }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值