Java - 私有内部类的私有成员与默认成员

Posted

技术标签:

【中文标题】Java - 私有内部类的私有成员与默认成员【英文标题】:Java - Private member vs default member of a private inner class 【发布时间】:2017-12-22 18:45:57 【问题描述】:

既然封闭类可以访问其内部类的私有字段,那么对于私有内部类,何时应将它们声明为私有、默认或公共?

【问题讨论】:

内部类也可以被其他不包含它的类使用。 也许:***.com/questions/1801718/… 内部类是公有的还是私有的? Why can outer Java classes access inner class private members?的可能重复 内部类是私有的。 ***.com/questions/1801718 试图解释为什么外部类可以访问内部类的私有字段,而不是它们的访问修饰符应该是什么。例如,请参阅 ArrayList$Sublist。它有 3 个私有字段和 1 个默认字段。 【参考方案1】:

不仅外部类,其他类也可以访问内部类及其成员。因此,当您想让内部类成员只能由其外部类访问时,您可以将它们声明为私有。考虑下面的例子

同一个包com.exercise.test中有2个类,其中的类是OtherClassSampleClassWithInner,其中包含内部类InnerClass

OtherClass 中声明为私有的 InnerClass 的成员不可访问。在SampleClassWithInner 中可以访问它

请参阅此代码以获得更清晰的信息

package com.exercise.test;
//import  com.exercise.test.SampleClassWithInner.InnerClass;

public class OtherClass 
public static void main(String[] args) 
    // TODO Auto-generated method stub
    SampleClassWithInner sampleobj = new SampleClassWithInner();
    SampleClassWithInner.InnerClass innerobj = sampleobj.new InnerClass();

    // innerobj.var1=5; //compile time error
    innerobj.setVar1(5); // ok works
    // System.out.println("value of inner variable declared in other
    // class"+innerobj.var1);// compile time error
    System.out.println("value of inner variable declared in other class " 

+ innerobj.getVar1());
        sampleobj.innerMethodDemo();
    


package com.exercise.test;

public class SampleClassWithInner 

class InnerClass 
    private int var1;
    private int var2;

    public int getVar1() 
        return var1;
    

    public void setVar1(int var1) 
        this.var1 = var1;
    

    public int getVar2() 
        return var2;
    

    public void setVar2(int var2) 
        this.var2 = var2;
    


public void innerMethodDemo() 
    InnerClass obj = new InnerClass();
    obj.var1 = 10;
    System.out.println("this is form the method in outer class " + 

obj.var1);

    
 

【讨论】:

该操作询问如果内部类已经有一个私有修饰符,私有修饰符将添加到您的代码中有何用途。当然,如果内部类是公共的,那么是的,但是如果内部类具有私有修饰符,那么 var1 和 var2 就没有使用修饰符【参考方案2】:

乍一看,在内部类的成员上指定访问修饰符似乎无关紧要。正如您所指出的,包含类无论如何都可以访问所有成员。

这里有一些额外的注意事项:

有时内部类被声明为public,并作为包含类的接口定义的一部分。也许外部类有一个返回内部类实例的方法。在这种情况下,内部类受制于与***类相同的成员可见性最佳实践。在这种情况下,最好保留实现细节private。 虽然编译器不会强制执行,但将内部类的成员标记为private 可以为未来的维护者记录这些成员不打算由外部类代码直接访问。当然,到那时,可能需要将内部类重构为它自己的***类。 有时内部类与仅在public 成员上运行的基于反射的框架结合使用。例如,Jackson JSON 序列化器默认只对public 成员运行。可以通过添加public getter 之类的操作使其在private 成员上运行。这是额外的工作,因此首先声明成员public 可能更方便。 如果上述几点不适用,并且没有任何其他要求,最简单和最短的代码是完全省略访问修饰符(默认/包私有)。这将是一个项目需要考虑的编码风格问题。

【讨论】:

【参考方案3】:

除非有理由使用包私有或公共可见性,否则将所有内容声明为私有是一种很好的风格。而这个原因应该不是更方便

所有非私有的东西都可以在你的类之外使用,因此对代码的任何非私有方面的更改可能会破坏其他代码位置,甚至是依赖于你的代码的外部代码。使重构和更改类的内部工作变得更加困难甚至有时甚至不可能。

private 内部类的特殊情况下,所有内容仅对您的包含类可见。那就是内部类成员的可见性并不重要。另一个极端,如果你正在开发一个库,通常的做法是只将接口公开为契约。完全隐藏实施细节。

【讨论】:

以上是关于Java - 私有内部类的私有成员与默认成员的主要内容,如果未能解决你的问题,请参考以下文章

外部类与内部类的访问

为啥子类可以访问具有内部类的超类的私有成员?

成员类访问修饰符

内部类

Java的静态成员类

各种内部类的总结