Java 如何从类外部访问内部类的私有属性?

Java 如何从类外部访问内部类的私有属性?,java,inner-classes,Java,Inner Classes,我读过关于静态内部类的这个概念:ViewHolder在ListView的适配器中声明为内部类,以增强getView()的性能 考虑下面的类 public class OuterClass{ public class InnerClass{ private int privateProperty= -2; } public static void main(String[] args) { OuterClass oc = new Oute

我读过关于静态内部类的这个概念:ViewHolder在ListView的适配器中声明为内部类,以增强getView()的性能

考虑下面的类

public class OuterClass{

    public class InnerClass{
        private int privateProperty= -2;
    }

    public static void main(String[] args) {
        OuterClass oc = new OuterClass();
        InnerClass ic = oc.new InnerClass();
        ic.privateProperty = -98;
    }
}
如果内部类包含私有属性,并且在外部类的方法内创建了内部类的对象,则可以使用直接访问内部类的私有属性点运算符

我在某个地方读到,内部类的私有属性是使用外部类的合成setter-getter方法访问的


我想澄清我的概念。

编译器生成方法来访问内部类的私有成员。如果编译示例代码并检查字节码,您会发现它的编写方式如下:

public class OuterClass{

    public class InnerClass{
        private int privateProperty= -2;
        static int access$002(InnerClass obj, int value) {
            obj.privateProperty = value;
            return value;
        }
    }

    public static void main(String[] args) {
        OuterClass oc = new OuterClass();
        InnerClass ic = oc.new InnerClass();
        InnerClass.access$002(ic, -98);
    }
}
public class OuterClass{
private InnerClass in;

public Class OuterClass() {
    in = new InnerClass();
}
//getters & setters
public void setInnerProperty(int x) {
    in.setPrivateProperty(x);
}

public class InnerClass{
    private int privateProperty= -2;
    //getters & setters
}

public static void main(String[] args) {
    OuterClass oc = new OuterClass();
    oc.setInnerProperty(98);
}
}
这条线的转换

ic.privateProperty = -98;
进入方法调用:

InnerClass.access$002(ic, -98);

与创建静态方法
InnerClass.access$002
一起由编译器完成。静态方法(由我的编译器命名为
access$002
)是您阅读过的“合成setter方法”的一个示例。因此,这两个类的字节码不会违反Java的访问规则。

编译器生成方法来访问内部类的私有成员。如果编译示例代码并检查字节码,您会发现它的编写方式如下:

public class OuterClass{

    public class InnerClass{
        private int privateProperty= -2;
        static int access$002(InnerClass obj, int value) {
            obj.privateProperty = value;
            return value;
        }
    }

    public static void main(String[] args) {
        OuterClass oc = new OuterClass();
        InnerClass ic = oc.new InnerClass();
        InnerClass.access$002(ic, -98);
    }
}
public class OuterClass{
private InnerClass in;

public Class OuterClass() {
    in = new InnerClass();
}
//getters & setters
public void setInnerProperty(int x) {
    in.setPrivateProperty(x);
}

public class InnerClass{
    private int privateProperty= -2;
    //getters & setters
}

public static void main(String[] args) {
    OuterClass oc = new OuterClass();
    oc.setInnerProperty(98);
}
}
这条线的转换

ic.privateProperty = -98;
进入方法调用:

InnerClass.access$002(ic, -98);

与创建静态方法
InnerClass.access$002
一起由编译器完成。静态方法(由我的编译器命名为
access$002
)是您阅读过的“合成setter方法”的一个示例。因此,这两个类的字节码不会违反Java的访问规则。

您的概念是错误的。。内部类只能在容器类内部使用,这个想法来自于这样一个概念,即您不想向开发人员公开不必要的类,这与项目的所有部分都不相关

在这种情况下,
内部类
将仅与
外部类
相关。大体上,您应该只为
OuterClasS
创建新的,OuterClasS将创建
InnerClass

所以应该是这样的:

public class OuterClass{

    public class InnerClass{
        private int privateProperty= -2;
        static int access$002(InnerClass obj, int value) {
            obj.privateProperty = value;
            return value;
        }
    }

    public static void main(String[] args) {
        OuterClass oc = new OuterClass();
        InnerClass ic = oc.new InnerClass();
        InnerClass.access$002(ic, -98);
    }
}
public class OuterClass{
private InnerClass in;

public Class OuterClass() {
    in = new InnerClass();
}
//getters & setters
public void setInnerProperty(int x) {
    in.setPrivateProperty(x);
}

public class InnerClass{
    private int privateProperty= -2;
    //getters & setters
}

public static void main(String[] args) {
    OuterClass oc = new OuterClass();
    oc.setInnerProperty(98);
}
}
如果你想改变它从主。。这是一种方法,但不推荐


希望这对你有所帮助你的想法是错误的。。内部类只能在容器类内部使用,这个想法来自于这样一个概念,即您不想向开发人员公开不必要的类,这与项目的所有部分都不相关

在这种情况下,
内部类
将仅与
外部类
相关。大体上,您应该只为
OuterClasS
创建新的,OuterClasS将创建
InnerClass

所以应该是这样的:

public class OuterClass{

    public class InnerClass{
        private int privateProperty= -2;
        static int access$002(InnerClass obj, int value) {
            obj.privateProperty = value;
            return value;
        }
    }

    public static void main(String[] args) {
        OuterClass oc = new OuterClass();
        InnerClass ic = oc.new InnerClass();
        InnerClass.access$002(ic, -98);
    }
}
public class OuterClass{
private InnerClass in;

public Class OuterClass() {
    in = new InnerClass();
}
//getters & setters
public void setInnerProperty(int x) {
    in.setPrivateProperty(x);
}

public class InnerClass{
    private int privateProperty= -2;
    //getters & setters
}

public static void main(String[] args) {
    OuterClass oc = new OuterClass();
    oc.setInnerProperty(98);
}
}
如果你想改变它从主。。这是一种方法,但不推荐


希望对你有所帮助。

不清楚你在问什么。重复的:抱歉,我的问题接近所告诉的链接,但我想弄清楚用于从外部类访问内部类的私有属性的合成访问器方法的概念。不清楚你在问什么。重复的:抱歉,我的问题接近所告诉的链接,但我想要弄清楚用于从外部类访问内部类的私有属性的合成访问器方法的概念,从客户机代码生成内部类的实例一点问题都没有。这就是为什么Java提供OP正在使用的语法--
oc.new InnerClass()
--它为实例化内部类实例提供外部类上下文。如果没有必要向开发人员公开
InnerClass
,那么它可以被声明为
private
OuterClass
。是的。。Java可以提供很多灵活性来使用它。。但是我写的方式是按照你的要求处理问题的正确方式。。有一个叫做信息隐藏的基础知识。试着读一读。。解决问题总有几种方法。但只有少数是好的解决方案。。始终坚持基本原则。。这将节省您以后的时间从客户机代码生成内部类的实例一点问题都没有。这就是为什么Java提供OP正在使用的语法--
oc.new InnerClass()
--它为实例化内部类实例提供外部类上下文。如果没有必要向开发人员公开
InnerClass
,那么它可以被声明为
private
OuterClass
。是的。。Java可以提供很多灵活性来使用它。。但是我写的方式是按照你的要求处理问题的正确方式。。有一个叫做信息隐藏的基础知识。试着读一读。。解决问题总有几种方法。但只有少数是好的解决方案。。始终坚持基本原则。。这将节省您以后的时间谢谢Ted,这是我正在寻找的答复,您能给我一些链接吗?我可以浏览一下,因为我找不到为内部类私有属性创建的编译时方法的适当文档。但还有一件事,我下载了jd-gui-0.3.6.windows反编译器,并尝试读取生成的.class文件。但是我仍然找不到访问器方法。@nits.kk-您不需要使用JDGUI。生成.class文件后,只需从命令行运行
javap-c OuterClass
javap-c OuterClass$InnerClass
(假设您的
路径设置正确)。@nits.kk-您可能还想看看。谢谢Ted,这是我想要的答复,你能不能给我一些链接,我可以通过,因为我找不到一些合适的文件进行编译