有关java私有变量访问的一个问题!!

1)访问非私有(private)变量
代码: 
 class A{
  public static int psi=-5;  //类变量
  static int si=-1;   //类变量(包)
  private static int ptsi=5;  //类变量(私有)
  protected static int prsi = 1100; //类变量(保护)
  
  public int pi = 100;   //实例变量
  int i = 1001;    //实例变量(包)
  private int pti = 1002;   //实例变量(私有)
  protected int pri = 1003;  //实例变量(保护)
    
 }
  
 class B{
  public static void main(String[] args){
   A a = new A();
   System.out.println( a.psi );
   System.out.println( a.si );
     System.out.println( a.prsi );
   
   System.out.println("--------------------------");
   System.out.println(A.psi );
   System.out.println(A.si );
   System.out.println(A.prsi );
   
   System.out.println("---------------------------");
   System.out.println(a.pi );
   System.out.println( a.prsi );
   
  }
 }
 
 
编译后:生成B.class和A.class两个文件,B.class反编译的结果如下:
 class B
 {
     B()
     {
     }
 
     public static void main(String args[])
     {
         A a = new A();
         A _tmp = a;
         System.out.println(A.psi);
         A _tmp1 = a;
         System.out.println(A.si);
         A _tmp2 = a;
         System.out.println(A.prsi);
         System.out.println("--------------------------");
         System.out.println(A.psi);
         System.out.println(A.si);
         System.out.println(A.prsi);
         System.out.println("---------------------------");
         System.out.println(a.pi);
         A _tmp3 = a;
         System.out.println(A.prsi);
     }
 }

结论:
 在B中,通过类访问静态变量和通过实例访问变量,增加了几个类型转换!
 
2)访问私有变量
代码:
public class A {
 public static int psiA= 10;  //类变量
 static int siA=110;   //类变量(包)
 private static int ptsiA=1110;  //类变量(私有)
 protected static int prsiA = 11100; //类变量(保护)
 
 public int piA = 1000;   //实例变量
 int iA = 1001;    //实例变量(包)
 private int ptiA = 1002;  //实例变量(私有)
 protected int priA = 1003;  //实例变量(保护)
 
 
 //内部类(静态成员类)
 public static class INB{
  public INB(){
  }
  
  public static int psiB=20;  //类变量
  static int siB=220;   //类变量(包)
  private static int ptsiB=2220;  //类变量(私有)
  protected static int prsiB = 22220; //类变量(保护)
    
  public void output(){
   
   A tmp = new A();
   System.out.println("CLASS A");
   System.out.println( A.psiA );    //访问包含类A的类变量(public)
   System.out.println( tmp.siA );  //package
   System.out.println( tmp.ptsiA);  //private
   System.out.println( A.ptsiA=9 );  
   //System.out.println( tmp.ptsiA=10 );   //在内部类里 实例可以对所有类变量赋值 在对私有类变量赋值时 导致反编译器出错
   System.out.println( tmp.ptiA =-4); //访问类A的私有实例变量 并赋值  
   System.out.println( tmp.priA =6 ); 
  }
  
  public static void main(String[] args ){
     INB t1 = new INB();
     t1.output();
  }
 }
  
 public static void main(String[] args ){
    INB b = new INB();
    b.output();
    System.out.println(INB.ptsiB );
 }
}

编译后:
生成2个文件A.class 和 A$B.class。A.class文件反编译结果:
public class A
{
    public static class INB
    {
        public void output()
        {
            A a = new A();           
            System.out.println("CLASS A:");
            System.out.println(A.psiA);
            A _tmp = a;
            System.out.println(A.siA);
            System.out.println(A.ptsiA);
            System.out.println(A.ptsiA = 9);
            System.out.println(a.ptiA = -4);
            System.out.println(a.priA = 6);
        }

        public static void main(String args[])
        {
            INB inb = new INB();
            inb.output();
        }

        public static int psiB = 20;
        static int siB = 220;
        private static int ptsiB = 2220;
        protected static int prsiB = 22220;
       
        public INB()
        {           
        }
    }

A$INB.class反编译的结果:
    public A()
    {
        piA = 1000;
        iA = 1001;
        ptiA = 1002;
        priA = 1003;
    }

    public static void main(String args[])
    {
        INB inb = new INB();
        inb.output();
        System.out.println(INB.ptsiB);
    }

    public static int psiA = 10;
    static int siA = 110;
    private static int ptsiA = 1110;
    protected static int prsiA = 11100;
    public int piA;
    int iA;
    private int ptiA;
    protected int priA;
    public static INB m = new INB();

}

public static class A$INB
{
    public void output()
    {
        A a = new A();       
        System.out.println("CLASS A:");
        System.out.println(A.psiA);
        A _tmp = a;
        System.out.println(A.siA);                              //通过实例访问类变量,自动转换成了类访问
        System.out.println(a.access$000());          //通过实例对包含类A的私有类变量访问 
        System.out.println(A.access$002(9));        //直接对包含类A的私有类变量赋值
        System.out.println(A.access$102(a, -4));  //对私有实例变量赋值 自动生成了类方法进行访问
        System.out.println(a.priA = 6);                      //对保护实例变量赋值
    }

    public static void main(String args[])
    {
        A$INB a$inb = new A$INB();
        a$inb.output();
    }
   
    public A$INB()
    {       
    }

}

结论:
1.对私有变量的访问,编译器自动产生非私有的访问方法(类方法或实例方法),并且把访问私有成员的表达式转换成这些方法的表达式!
2.acess$XXXX方法由编译系统生成,后面两位数字应该代表操作类型,前面的数字代表私有变量编号
3.在程序中,无论是类方法还是实例方法,你都不能创建acess$XXXX() (XXXX为数字)的方法!
4.程序中被注解掉的System.out.println( tmp.ptsiA=10 )可以编译通过,但是反编译的时候居然使反编译程序出错了,所以%^&*()


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值