最近学习了反射,发现用反射机制完全可以访问java类中的私有的成员,例如,可以用私有的构造方法创建出实例来,可以用反射来修改私有成员变量的值,让我很疑惑的是java中提供的安全机制(如有private修饰符的成员不能被类外部的其他类访问)还有意义吗?希望各位高手们来探讨一下!

解决方案 »

  1.   

    我很疑惑! 你的标题为什么是?  一个"大学生"关于java 反射的问题?为什么一定要加上一个大学生呢?! 说正事...问题:可以用私有的构造方法创建出实例来,可以用反射来修改私有成员变量的值!ans:
    贴出你代码!来证明上面的观点!
    修饰符的成员不能被类外部的其他类访问! 这个是没有问题的!..如果你觉得可以。你写个例子证明下也行! 期待中.>!..... 
      

  2.   

    首先申明一下,我写"  一个大学生关于java反射的疑惑",是为了吸引大家的注意,好让大家来讨论,我也好得到答案.package com.sun.Enum;public class ClassOfTest {
    public ClassOfTest(){}
    public ClassOfTest(String a,int b){//提供一个两个参数构造方法
    this.setA(a);
    this.setB(b);
    }
    private ClassOfTest(String a,int b,String c,int d){//提供一个四个参数的构造方法
    this.setA(a);
    this.setB(b);
    this.c=c;
    this.d=d;

    }

    public int add(int x,int y){
    return x+y;
    }
    public void setA(String a) {
    this.a = a;
    }
    public String getA() {
    return a;
    } public void setB(int b) {
    this.b = b;
    }
    public int getB() {
    return b;
    } private String a;//字段
    private int b;
    public String c;
    public int d;
    }//以上的是一个实体类的代码
    //测试类的代码如下
    package com.sun.Enum;import java.lang.reflect.Array;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;import com.sun.org.apache.xml.internal.serializer.utils.StringToIntTable;public class Test {
    public static void main(String[] args) throws Exception{
    //演示Constractor类

    //获得ClassOfTest的构造两个参数的构造方法
    Constructor<ClassOfTest> cotConstructor=ClassOfTest.class.getConstructor(String.class,int.class);
    //用此构造方法创建一个ClassOfTest的对象
    ClassOfTest cot=cotConstructor.newInstance("abc",1);

    //用反射可以用私有的构造方法创建出对象
    //getDeclaredConstructor(String.class,int.class,String.class,int.class)强制获取构造方法,不管是什么修饰符
    Constructor<ClassOfTest> cotConstructor2=ClassOfTest.class.getDeclaredConstructor(String.class,int.class,String.class,int.class);
    //强制的使私有的构造方法可以被访问
    cotConstructor2.setAccessible(true);
    ClassOfTest cot2=cotConstructor2.newInstance("我的",7,"def",9);
    System.out.println("私有的方法"+cot2.getA()); //此时是用无参的构造方法创建对象
    //getField()不能获得私有的成员变量,getDeclaredField()能获得私有的成员变量
    Field fieldA=ClassOfTest.class.getDeclaredField("a");

    //强制设置可以获得私有变量的值,叫暴力反射
    fieldA.setAccessible(true);
    System.out.println(fieldA.get(cot));


    System.out.println();
    System.out.println();

    //获得所有的成员变量
    System.out.println("开始");
    Field[] fields=ClassOfTest.class.getDeclaredFields();
    for(int i=0;i<fields.length;i++){
    //因为是同一份字节码,所以用的是"=="
    if(fields[i].getType()==String.class){
    fields[i].setAccessible(true);//暴力反射
    fields[i].set(cot, "String");//替换
    }
    }
    for(int i=0;i<fields.length;i++){
    //反射可以访问私有变量
    fields[i].setAccessible(true);//暴力反射
    System.out.println(fields[i].get(cot));//替换
    }
    System.out.println("结束");
    System.out.println(cot.getA());
    System.out.println(cot.getB());

    System.out.println();
    System.out.println();

    }
    }
    以上是我已经验证了的代码,由于编辑器的原因,结构不算清晰,可能你看不懂,也可能有一些小错误,请原谅!
      

  3.   

    这个问题值得考虑下,个人认为
    1.通过访问限制可以减少很多没有通过访问修饰而产生的错误。
        例如:我定义了一个接口A然后又两个实现类分别是C和D,我用C类实现是可能在我的类中有关属性E
              在我实现接口A是通过修改E属性很方便的完成我在A接口的方法和业务逻辑,而我用D类实现A接口
              并没有在类中定义E属性同样我也很方便的完成我在A接口的方法和业务逻辑,那么如果我们在写程序
              时如果依赖了C类的E属性那么程序可能莫名的报错,程序很不健壮。
    2.只要你是程序那么你的所有数据就都会被加载的内存中,我同样可以修改内存里面的值而且。(网上内存注
            册机很多的)。也就是说我要修改内存中某个地址的值是不能被完全阻止的。
    3.通过反射我们可以很方便的完成许多事情。合了而不为呢。(动态将一个对象转换成一个json对象)
              
      

  4.   

    在不信的话,你可以到www.verycd.com这个网站上去下载"张孝祥Java高新技术"的视频教材(只需要在搜索框里打入"张孝祥Java高新技术"这几个字,一搜就出来了),里面讲了jdk1.5的一些新特性,其中有有关java反射的讲解
      

  5.   

    你的确证明了! 能够访问类的私有成员!如有private修饰符的成员能被类外部的其他类访问 ? 还有意义吗? 我想说的是当然有意义? 怎么说呢 ? 任何可以肯定只是该类的一个 “助手”方法的方法,都可以把它指定为private ,以确保存不会在包内的其它地方  "误用"  它 ,于是也就防止了你会去修改和删除这个方法! -----------出自 think in java !private 安全机制从上面话来讲,用private 只是怕你 误用 : 而非 禁用! 但是你访问 这么私有成员是通过一系列的 "手段"[指反射]来实现的!这样说来 private 的作用 和可以通过某些方法来访问 并不冲突!楼主你认为呢?!  打个比方 private 只是一把锁 ,可偏偏你要使用"暴力"来把门打烂!  这样说来你家锁也可以不要了.!你说是吗???
      

  6.   

    反射这东西,很好很强大,会的人少,用得更少。
    楼主所说的用反射来访问类的私有属性和方法,这只是java提供的一种机制。
    说明一下,使用反射改变了原有的属性值有没有实际意义?
      

  7.   

    private 是防止外部类访问的,有反射肯定可以了
      

  8.   

    "private是给编译器看的。"说的也很有道理
      

  9.   

     lz 学得这么用心! 。
    毕业了,最好去个大企业吧! it 行业也不像圈子里面的人说得这么苦。好好加油。相当看好你!有能力 几十w 年薪的岗位还是有不少的!