精华内容
下载资源
问答
  • 的属性设置成private其他类可以用get/set方法访问,那的方法声明成private呢,那么其他类怎么访问 呢,还是说直接没法访问
  • 此文文转载文 原文链接: ...在Java编程中,使用private关键字修饰了某个成员,只有这个成员所在的和这个的方法可以使用,其他都无法访问到这个pri...

    此文文转载文

    原文链接: https://droidyue.com/blog/2014/10/02/the-private-modifier-in-java/

    这篇文章通过反编译讲解了为什么内部类能用外部类private成员和为什么外部类能用内部类private成员

    在Java编程中,使用private关键字修饰了某个成员,只有这个成员所在的类和这个类的方法可以使用,其他的类都无法访问到这个private成员。

    上面描述了private修饰符的基本职能,今天来研究一下private功能失效的情况。

    Java内部类

    在Java中相信很多人都用过内部类,Java允许在一个类里面定义另一个类,类里面的类就是内部类,也叫做嵌套类。一个简单的内部类实现可以如下

    class OuterClass {
        class InnerClass{
        }
    }
    

    今天的问题和Java内部类相关,只涉及到部分和本文研究相关的内部类知识,具体关于Java内部类后续的文章会介绍。


    第一次失效?

    一个我们在编程中经常用到的场景,就是在一个内部类里面访问外部类的private成员变量或者方法,这是可以的。如下面的代码实现。

    public class OuterClass {
      private String language = "en";
      private String region = "US";
      
      
      public class InnerClass {
          public void printOuterClassPrivateFields() {
              String fields = "language=" + language + ";region=" + region;
              System.out.println(fields);
          }
      }
      
      public static void main(String[] args) {
          OuterClass outer = new OuterClass();
          OuterClass.InnerClass inner = outer.new InnerClass();
          inner.printOuterClassPrivateFields();
      }
    }
    

    这是为什么呢,不是private修饰的成员只能被成员所述的类才能访问么?难道private真的失效了么?

    编译器在捣鬼?

    我们使用javap命令查看一下生成的两个class文件

    OuterClass的反编译结果:

    15:30 $ javap -c  OuterClass
    Compiled from "OuterClass.java"
    public class OuterClass extends java.lang.Object{
    public OuterClass();
      Code:
       0:  aload_0
       1:  invokespecial    #11; //Method java/lang/Object."<init>":()V
       4:  aload_0
       5:  ldc  #13; //String en
       7:  putfield #15; //Field language:Ljava/lang/String;
       10: aload_0
       11: ldc  #17; //String US
       13: putfield #19; //Field region:Ljava/lang/String;
       16: return
    
    public static void main(java.lang.String[]);
      Code:
       0:  new  #1; //class OuterClass
       3:  dup
       4:  invokespecial    #27; //Method "<init>":()V
       7:  astore_1
       8:  new  #28; //class OuterClass$InnerClass
       11: dup
       12: aload_1
       13: dup
       14: invokevirtual    #30; //Method java/lang/Object.getClass:()Ljava/lang/Class;
       17: pop
       18: invokespecial    #34; //Method OuterClass$InnerClass."<init>":(LOuterClass;)V
       21: astore_2
       22: aload_2
       23: invokevirtual    #37; //Method OuterClass$InnerClass.printOuterClassPrivateFields:()V
       26: return
    
    static java.lang.String access$0(OuterClass);
      Code:
       0:  aload_0
       1:  getfield #15; //Field language:Ljava/lang/String;
       4:  areturn
    
    static java.lang.String access$1(OuterClass);
      Code:
       0:  aload_0
       1:  getfield #19; //Field region:Ljava/lang/String;
       4:  areturn
    
    }
    

    咦?不对,在OuterClass中我们并没有定义这两个方法

    static java.lang.String access$0(OuterClass);
      Code:
       0:  aload_0
       1:  getfield #15; //Field language:Ljava/lang/String;
       4:  areturn
    
    static java.lang.String access$1(OuterClass);
      Code:
       0:  aload_0
       1:  getfield #19; //Field region:Ljava/lang/String;
       4:  areturn
    
    }
    

    从给出来的注释来看,access$0返回outerClass的language属性;access$1返回outerClass的region属性。并且这两个方法都接受OuterClass的实例作为参数。这两个方法为什么生成呢,有什么作用呢?我们看一下内部类的反编译结果就知道了:

    OuterClass$InnerClass的反编译结果:

    15:37 $ javap -c OuterClass\$InnerClass
    Compiled from "OuterClass.java"
    public class OuterClass$InnerClass extends java.lang.Object{
    final OuterClass this$0;
    
    public OuterClass$InnerClass(OuterClass);
      Code:
       0:  aload_0
       1:  aload_1
       2:  putfield #10; //Field this$0:LOuterClass;
       5:  aload_0
       6:  invokespecial    #12; //Method java/lang/Object."<init>":()V
       9:  return
    
    public void printOuterClassPrivateFields();
      Code:
       0:  new  #20; //class java/lang/StringBuilder
       3:  dup
       4:  ldc  #22; //String language=
       6:  invokespecial    #24; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
       9:  aload_0
       10: getfield #10; //Field this$0:LOuterClass;
       13: invokestatic #27; //Method OuterClass.access$0:(LOuterClass;)Ljava/lang/String;
       16: invokevirtual    #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       19: ldc  #37; //String ;region=
       21: invokevirtual    #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       24: aload_0
       25: getfield #10; //Field this$0:LOuterClass;
       28: invokestatic #39; //Method OuterClass.access$1:(LOuterClass;)Ljava/lang/String;
       31: invokevirtual    #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       34: invokevirtual    #42; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       37: astore_1
       38: getstatic    #46; //Field java/lang/System.out:Ljava/io/PrintStream;
       41: aload_1
       42: invokevirtual    #52; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       45: return
    }
    

    下面代码调用access$0的代码,其目的是得到OuterClass的language 私有属性。

    1 13:   invokestatic #27; //Method OuterClass.access$0:(LOuterClass;)Ljava/lang/String;
    下面代码调用了access$1的代码,其目的是得到OutherClass的region 私有属性。
    
    1 28:   invokestatic #39; //Method OuterClass.access$1:(LOuterClass;)Ljava/lang/String;
    

    注意:在内部类构造的时候,会将外部类的引用传递进来,并且作为内部类的一个属性,所以内部类会持有一个其外部类的引用。
    this$0就是内部类持有的外部类引用,通过构造方法传递引用并赋值。

    final OuterClass this$0;
    
    public OuterClass$InnerClass(OuterClass);
      Code:
       0:  aload_0
       1:  aload_1
       2:  putfield #10; //Field this$0:LOuterClass;
       5:  aload_0
       6:  invokespecial    #12; //Method java/lang/Object."<init>":()V
       9:  return
    

    小结
    这部分private看上去失效可,实际上并没有失效,因为当内部类调用外部类的私有属性时,其真正的执行是调用了编译器生成的属性的静态方法(即acess$0,access$1等)来获取这些属性值。这一切都是编译器的特殊处理。

    这次也失效?

    如果说上面的写法很常用,那么这样的写法是不是很少接触,但是却可以运行。

    public class AnotherOuterClass {
      public static void main(String[] args) {
          InnerClass inner = new AnotherOuterClass().new InnerClass();
          System.out.println("InnerClass Filed = " + inner.x);
      }
    
      class InnerClass {
          private int x = 10;
      }
    
    }
    

    和上面一样,使用javap反编译看一下。不过这次我们先看一下InnerClass的结果

    16:03 $ javap -c AnotherOuterClass\$InnerClass
    Compiled from "AnotherOuterClass.java"
    class AnotherOuterClass$InnerClass extends java.lang.Object{
    final AnotherOuterClass this$0;
    
    AnotherOuterClass$InnerClass(AnotherOuterClass);
      Code:
       0:  aload_0
       1:  aload_1
       2:  putfield #12; //Field this$0:LAnotherOuterClass;
       5:  aload_0
       6:  invokespecial    #14; //Method java/lang/Object."<init>":()V
       9:  aload_0
       10: bipush   10
       12: putfield #17; //Field x:I
       15: return
    
    static int access$0(AnotherOuterClass$InnerClass);
      Code:
       0:  aload_0
       1:  getfield #17; //Field x:I
       4:  ireturn
    
    }
    

    又出现了,编译器又自动生成了一个获取私有属性的后门方法access$0一次来获取x的值。

    AnotherOuterClass.class的反编译结果

    16:08 $ javap -c AnotherOuterClass
    Compiled from "AnotherOuterClass.java"
    public class AnotherOuterClass extends java.lang.Object{
    public AnotherOuterClass();
      Code:
       0:  aload_0
       1:  invokespecial    #8; //Method java/lang/Object."<init>":()V
       4:  return
    
    public static void main(java.lang.String[]);
      Code:
       0:  new  #16; //class AnotherOuterClass$InnerClass
       3:  dup
       4:  new  #1; //class AnotherOuterClass
       7:  dup
       8:  invokespecial    #18; //Method "<init>":()V
       11: dup
       12: invokevirtual    #19; //Method java/lang/Object.getClass:()Ljava/lang/Class;
       15: pop
       16: invokespecial    #23; //Method AnotherOuterClass$InnerClass."<init>":(LAnotherOuterClass;)V
       19: astore_1
       20: getstatic    #26; //Field java/lang/System.out:Ljava/io/PrintStream;
       23: new  #32; //class java/lang/StringBuilder
       26: dup
       27: ldc  #34; //String InnerClass Filed =
       29: invokespecial    #36; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
       32: aload_1
       33: invokestatic #39; //Method AnotherOuterClass$InnerClass.access$0:(LAnotherOuterClass$InnerClass;)I
       36: invokevirtual    #43; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
       39: invokevirtual    #47; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
       42: invokevirtual    #51; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       45: return
    
    }
    

    其中这句调用就是外部类通过内部类的实例获取私有属性x的操作

    1 33:   invokestatic #39; //Method AnotherOuterClass$InnerClass.access$0:(LAnotherOuterClass$InnerClass;)I
    

    再来个总结

    其中java官方文档 有这样一句话

    if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

    意思是 如果(内部类的)成员和构造方法设定成了私有修饰符,当且仅当其外部类访问时是允许的。

    如何让内部类私有成员不被外部访问

    相信看完上面两部分,你会觉得,内部类的私有成员想不被外部类访问都很困难吧,谁让编译器“爱管闲事”呢,其实也是可以做到的。那就是使用匿名内部类。

    由于mRunnable对象的类型为Runnable,而不是匿名内部类的类型(我们无法正常拿到),而Runanble中没有x这个属性,所以mRunnable.x是不被允许的。

    public class PrivateToOuter {
      Runnable mRunnable = new Runnable(){
          private int x=10;
          @Override
          public void run() {
              System.out.println(x);
          }
      };
    
      public static void main(String[] args){
          PrivateToOuter p = new PrivateToOuter();
          //System.out.println("anonymous class private filed= "+ p.mRunnable.x); //not allowed
          p.mRunnable.run(); // allowed
      }
    }
    

    最后总结

    在本文中,private表面上看上去失效了,但实际上是没有的,而是在调用时通过间接的方法来获取私有的属性。
    Java的内部类构造时持有对外部类的应用,C++不会,这一点和C++不一样。

    展开全文
  • 在main方法中访问类private变量

    千次阅读 2014-11-19 19:47:39
    关于“在本访问私有静态变量”的一点疑惑解析 代码如下: public class StaticVar { private static int x = 100; public static void main(String[] args) { StaticVar var1 = new StaticVar(); ...

    问题:下述代码,在main方法中访问x变量是否可行?程序是否可正常运行?

    这不是一个特别的问题,只是猛然间看到后,第一反应错误,权且一记!

    答案:在main方法中可以访问x变量,程序也可以正常运行。

    解析:私有变量只能在本类作用域中才能被访问,类作用域指的是紧跟在类名之后的那对大括号之间的地方。main方法比较特殊,是Java程序的入口,但在本例中,它同时也是StaticVar类定义的静态方法,所以可以在main方法中访问到x变量。

    public class StaticVar {
    
        private static int x = 100;
    
        public static void main(String[] args) {
            int var1 = StaticVar.x;
            int var2 = new StaticVar().x;
            System.out.println(var1);// 100
            System.out.println(var2);// 100
        }
    
    }

     

    展开全文
  • 在Java编程中,使用private关键字修饰了某个成员,只有这个成员所在的和这个的方法可以使用,其他都无法访问到这个private成员。 上面描述了private修饰符的基本职能,今天来研究一下private功能失效的情况...

    在Java编程中,使用private关键字修饰了某个成员,只有这个成员所在的类和这个类的方法可以使用,其他的类都无法访问到这个private成员。

    上面描述了private修饰符的基本职能,今天来研究一下private功能失效的情况。

    Java内部类
    在Java中相信很多人都用过内部类,Java允许在一个类里面定义另一个类,类里面的类就是内部类,也叫做嵌套类。一个简单的内部类实现可以如下
    class OuterClass {
    class InnerClass{
    }
    }
    今天的问题和Java内部类相关,只涉及到部分和本文研究相关的内部类知识,具体关于Java内部类后续的文章会介绍。

    第一次失效?
    一个我们在编程中经常用到的场景,就是在一个内部类里面访问外部类的private成员变量或者方法,这是可以的。如下面的代码实现。

    public class OuterClass {
    private String language = “en”;
    private String region = “US”;

    public class InnerClass {
    public void printOuterClassPrivateFields() {
    String fields = “language=” + language + “;region=” + region;
    System.out.println(fields);
    }
    }

    public static void main(String[] args) {
    OuterClass outer = new OuterClass();
    OuterClass.InnerClass inner = outer.new InnerClass();
    inner.printOuterClassPrivateFields();
    }
    }
    这是为什么呢,不是private修饰的成员只能被成员所述的类才能访问么?难道private真的失效了么?

    编译器在捣鬼?
    我们使用javap命令查看一下生成的两个class文件

    OuterClass的反编译结果

    15:30 $ javap -c OuterClass
    Compiled from “OuterClass.java”
    public class OuterClass extends java.lang.Object{
    public OuterClass();
    Code:
    0: aload_0
    1: invokespecial #11; //Method java/lang/Object.""😦)V
    4: aload_0
    5: ldc #13; //String en
    7: putfield #15; //Field language:Ljava/lang/String;
    10: aload_0
    11: ldc #17; //String US
    13: putfield #19; //Field region:Ljava/lang/String;
    16: return

    public static void main(java.lang.String[]);
    Code:
    0: new #1; //class OuterClass
    3: dup
    4: invokespecial #27; //Method “”😦)V
    7: astore_1
    8: new #28; //class OuterClassKaTeX parse error: Expected 'EOF', got '#' at position 73: …vokevirtual #̲30; //Method ja…InnerClass."":(LOuterClass;)V
    21: astore_2
    22: aload_2
    23: invokevirtual #37; //Method OuterClass$InnerClass.printOuterClassPrivateFields:()V
    26: return

    static java.lang.String access$0(OuterClass);
    Code:
    0: aload_0
    1: getfield #15; //Field language:Ljava/lang/String;
    4: areturn

    static java.lang.String access$1(OuterClass);
    Code:
    0: aload_0
    1: getfield #19; //Field region:Ljava/lang/String;
    4: areturn

    }
    咦?不对,在OuterClass中我们并没有定义这两个方法

    static java.lang.String access$0(OuterClass);
    Code:
    0: aload_0
    1: getfield #15; //Field language:Ljava/lang/String;
    4: areturn

    static java.lang.String access$1(OuterClass);
    Code:
    0: aload_0
    1: getfield #19; //Field region:Ljava/lang/String;
    4: areturn

    }
    从给出来的注释来看,access$0返回outerClass的language属性;access$1返回outerClass的region属性。并且这两个方法都接受OuterClass的实例作为参数。这两个方法为什么生成呢,有什么作用呢?我们看一下内部类的反编译结果就知道了。

    OuterClass$InnerClass的反编译结果

    15:37 $ javap -c OuterClass$InnerClass
    Compiled from “OuterClass.java”
    public class OuterClass$InnerClass extends java.lang.Object{
    final OuterClass this$0;

    public OuterClass$InnerClass(OuterClass);
    Code:
    0: aload_0
    1: aload_1
    2: putfield #10; //Field this$0:LOuterClass;
    5: aload_0
    6: invokespecial #12; //Method java/lang/Object.""😦)V
    9: return

    public void printOuterClassPrivateFields();
    Code:
    0: new #20; //class java/lang/StringBuilder
    3: dup
    4: ldc #22; //String language=
    6: invokespecial #24; //Method java/lang/StringBuilder."":(Ljava/lang/String;)V
    9: aload_0
    10: getfield #10; //Field this$0:LOuterClass;
    13: invokestatic #27; //Method OuterClass.access$0:(LOuterClass;)Ljava/lang/String;
    16: invokevirtual #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    19: ldc #37; //String ;region=
    21: invokevirtual #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    24: aload_0
    25: getfield #10; //Field this$0:LOuterClass;
    28: invokestatic #39; //Method OuterClass.access$1:(LOuterClass;)Ljava/lang/String;
    31: invokevirtual #33; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
    34: invokevirtual #42; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    37: astore_1
    38: getstatic #46; //Field java/lang/System.out:Ljava/io/PrintStream;
    41: aload_1
    42: invokevirtual #52; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
    45: return
    }
    下面代码调用access$0的代码,其目的是得到OuterClass的language 私有属性。

    1
    13: invokestatic #27; //Method OuterClass.access$0:(LOuterClass;)Ljava/lang/String;
    下面代码调用了access$1的代码,其目的是得到OutherClass的region 私有属性。

    1
    28: invokestatic #39; //Method OuterClass.access$1:(LOuterClass;)Ljava/lang/String;
    注意:在内部类构造的时候,会将外部类的引用传递进来,并且作为内部类的一个属性,所以内部类会持有一个其外部类的引用。
    this$0就是内部类持有的外部类引用,通过构造方法传递引用并赋值。

    final OuterClass this$0;

    public OuterClass$InnerClass(OuterClass);
    Code:
    0: aload_0
    1: aload_1
    2: putfield #10; //Field this$0:LOuterClass;
    5: aload_0
    6: invokespecial #12; //Method java/lang/Object.""😦)V
    9: return
    小结
    这部分private看上去失效可,实际上并没有失效,因为当内部类调用外部类的私有属性时,其真正的执行是调用了编译器生成的属性的静态方法(即acess$0,access$1等)来获取这些属性值。这一切都是编译器的特殊处理。

    这次也失效?
    如果说上面的写法很常用,那么这样的写法是不是很少接触,但是却可以运行。

    16:03 $ javap -c AnotherOuterClass$InnerClass
    Compiled from “AnotherOuterClass.java”
    class AnotherOuterClass$InnerClass extends java.lang.Object{
    final AnotherOuterClass this$0;

    AnotherOuterClass$InnerClass(AnotherOuterClass);
    Code:
    0: aload_0
    1: aload_1
    2: putfield #12; //Field this$0:LAnotherOuterClass;
    5: aload_0
    6: invokespecial #14; //Method java/lang/Object.""😦)V
    9: aload_0
    10: bipush 10
    12: putfield #17; //Field x:I
    15: return

    static int access0(AnotherOuterClass0(AnotherOuterClassInnerClass);
    Code:
    0: aload_0
    1: getfield #17; //Field x:I
    4: ireturn

    }
    又出现了,编译器又自动生成了一个获取私有属性的后门方法access$0一次来获取x的值。

    AnotherOuterClass.class的反编译结果

    16:08 $ javap -c AnotherOuterClass
    Compiled from “AnotherOuterClass.java”
    public class AnotherOuterClass extends java.lang.Object{
    public AnotherOuterClass();
    Code:
    0: aload_0
    1: invokespecial #8; //Method java/lang/Object.""😦)V
    4: return

    public static void main(java.lang.String[]);
    Code:
    0: new #16; //class AnotherOuterClassKaTeX parse error: Expected 'EOF', got '#' at position 35: …up 4: new #̲1; //class Anot…InnerClass."":(LAnotherOuterClass;)V
    19: astore_1
    20: getstatic #26; //Field java/lang/System.out:Ljava/io/PrintStream;
    23: new #32; //class java/lang/StringBuilder
    26: dup
    27: ldc #34; //String InnerClass Filed =
    29: invokespecial #36; //Method java/lang/StringBuilder."":(Ljava/lang/String;)V
    32: aload_1
    33: invokestatic #39; //Method AnotherOuterClass$InnerClass.access0:(LAnotherOuterClass0:(LAnotherOuterClassInnerClass;)I
    36: invokevirtual #43; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
    39: invokevirtual #47; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
    42: invokevirtual #51; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
    45: return

    }
    其中这句调用就是外部类通过内部类的实例获取私有属性x的操作

    1
    33: invokestatic #39; //Method AnotherOuterClass$InnerClass.access0:(LAnotherOuterClass0:(LAnotherOuterClassInnerClass;)I
    再来个总结
    其中java官方文档 有这样一句话

    if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

    意思是 如果(内部类的)成员和构造方法设定成了私有修饰符,当且仅当其外部类访问时是允许的。

    如何让内部类私有成员不被外部访问
    相信看完上面两部分,你会觉得,内部类的私有成员想不被外部类访问都很困难吧,谁让编译器“爱管闲事”呢,其实也是可以做到的。那就是使用匿名内部类。

    由于mRunnable对象的类型为Runnable,而不是匿名内部类的类型(我们无法正常拿到),而Runanble中没有x这个属性,所以mRunnable.x是不被允许的。

    public class PrivateToOuter {
     Runnable mRunnable = new Runnable(){
         private int x=10;
         @Override
         public void run() {
             System.out.println(x);
         }
     };
    
     public static void main(String[] args){
         PrivateToOuter p = new PrivateToOuter();
         //System.out.println("anonymous class private filed= "+ p.mRunnable.x); //not allowed
         p.mRunnable.run(); // allowed
     }
    }
    

    最后总结
    在本文中,private表面上看上去失效了,但实际上是没有的,而是在调用时通过间接的方法来获取私有的属性。
    Java的内部类构造时持有对外部类的应用,C++不会,这一点和C++不一样。

    展开全文
  • 外部可以访问内部类private变量

    千次阅读 2018-07-12 21:07:29
    在讲Singleton时我举例时用过这样一段代码:public class SingletonDemo ... private static class SingletonHolder{ private static SingletonDemo instance=new SingletonDemo(); } private SingletonDemo(){ ...
    在讲Singleton时我举例时用过这样一段代码:
    public class SingletonDemo {
        private static class SingletonHolder{
            private static SingletonDemo instance=new SingletonDemo();
        }
        private SingletonDemo(){
            System.out.println("Singleton has loaded");
        }
        public static SingletonDemo getInstance(){
            return SingletonHolder.instance;
        }
    }

    相信你一定发现了一个问题:外部类中的getInstance()方法调用了内部类SingletonHolder中的private变量instance。

    这就像是:

    老师可以检查教室中的学生书包里有没有卫生巾。

    坑爹啊!

    开始时候博主想,会不会是因为静态类在编译时结构特殊,才可以访问,然后做了个测试.......

    class Outer{
        class Inner{
            private int number=5;
        }
        public int getNumber(){
            return new Inner().number;
        }
    }
    public class Hello {
        public static void main(String[] args){
            System.out.println(new Outer().getNumber());
        }
    }

    然后跑起来了.......输出了5........

    坑爹啊!

    然后查了下,Java规范里确实规定了外部类可以访问内部类的private/protected变量,就像访问自己的private/protected变量一样.........实际上,编译器实现的时候是这样的:

    Outer类和Inner类不再是嵌套结构,而是变为一个包中的两个类,然后,对于private变量的访问,编译器会生成一个accessor函数.......

    嗯,反正这条记住就好。

    展开全文
  • 通过Person中的set()方法和get()方法设置并获取,在这里我们要注意的是set方法一般无返回值但是有参数(参数来自调用ser方法的),get方法有返回值但无参数,主要用于向主类中传递private修饰的数据,而我们则...
  • Java外部可以访问内部类private变量

    千次阅读 2019-04-04 15:05:05
    在讲Singleton时我举例时用过这样一段代码: public class SingletonDemo { private static class SingletonHolder{ private static SingletonDemo instance=new SingletonDemo();... private SingletonD...
  • 一般在其他类中是不能这个得到中private属性和访问private方法的,但天无绝人之路,java强大的反射机制可以完成这个任务。 建一个测试A: package com.shao.test; public class A { private String testStr...
  • 接触过面向对象编程的朋友们都知道中的访问控制符无非有...Protected: 使派生也可以访问其数据,但是又不想让其他的函数或进行访问 Private: 只有他所在的成员函数可以访问   在没有继承这一概念前,我们先
  • 如何访问类中的private成员变量

    千次阅读 2016-05-23 16:29:23
    总所周知,中的private属性的成员变量在外是无法访问的,今天我们探讨的就是如何在访问private属性的成员变量。我们先来看一个简单的例子:class STU { public: STU() { x = 5; y = 10; } private: ...
  • C++ 类访问控制public/private/protected探讨 摘要:本文是从饮水思源BBS C/C++版上一篇帖子引发的思考。当时看到帖子,突然觉得平时见惯了的,在这里似乎变得陌生了,究竟访问控制符怎样起作用,怎样使用...
  • C# 方法默认访问级别 : private C# 默认访问级别 : internalpublic:访问不受限制。protected:访问仅限于包含或从包含派生的类型。Internal:访问仅限于当前程序集。protected internal:访问限制到当前程序集...
  • 内部private来修饰

    千次阅读 2017-11-24 15:43:42
    private修饰的内部只能在它所属的外部访问 class Outer{private int num = 10;public int getNum(){ return num; }public void setNum(int num){ this.num = num; }//内部的定义 private class ...
  • 转自:mtjp C++中 public,protected, private 访问标号小结 ...不能被任何其他访问,该的对象也不能访问。 protected:可以被1.该中的函数、2.子类的函数、以及3.其友元函数访问。 但不能被该的对象访问...
  • 转自C++ 类访问控制(public/protected/private) C++中 public,protected, private 访问标号小结 第一:private, public, protected 访问标号的访问范围。 private:只能由1.该类中的函数、2.其...
  • 关于内部是如何获取外部private属性上一段代码:public class OuterClass { private static String language = "en"; private String region = "US"; private String li; private void kk() { System.out....
  • (1)不继承方面来说,private,public,protected...不能被任何其他访问,该的对象也不能访问。 protected: 可以被1.该中的函数、2.子类的函数、以及3.其友元函数访问。 但不能被该的对象访问。 public: ...
  • 不能被任何其他访问,该的对象也不能访问。 protected:可以被1.该中的函数、2.子类的函数、以及3.其友元函数访问。 但不能被该的对象访问。 public:可以被1.该中的函数、2.子类的函数、3.其...
  • 派生可以访问基类的private成员吗

    千次阅读 2012-05-20 21:42:37
    1.从派生的使用者来讲, 所有的基类方法和成员都是private的,不可访问 2.从派生内部来讲, 除了基类的private的方法和成员,其他的都可访问
  •   ...C++ 类访问控制(public/protected/private) C++中 public,protected, private 访问标号小结 第一:private, public, protected 访问标号的访问范围。 private:只能由1.该类中的函数、
  • Java,在一个中,为了不让外界访问到某些属性和方法,通常将其设置为private,用正常的方式(对象名.属性名,对象名.方法名)将无法访问此属性与方法,但有没有其他方法可以访问呢?答案是有的,这就是java反射...
  • 转自:http://www.cnblogs.com/yanqi0124/p/3828507.html私有成员变量的概念,在脑海中的现象是,以private关键字声明,是的实现部分,不对外公开,不能在对象外部访问对象的私有成员变量. 然而,在实现拷贝构造...
  • 的属性中,有一些是属于中间变量,外部不需要知道这些数据的值,因此需要对访问的权限进行控制,避免一个中的行为干涉到其他类,这样的方法也叫“封装”。 一般来说,权限分为三种,public(默认),private...
  • private访问权限

    2012-05-17 03:00:55
    非常基础的概念问题 ...不能被任何其他访问,该的对象也不能访问。 protected :可以被1.该中的函数、2.子类的函数、以及3.其友元函数访问。 但不能被该的对象访问。 public :可以被1.该中的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 591,724
精华内容 236,689
关键字:

其他类怎么访问private