受保护/公共内部类

15

有人能否解释一下 protected / public 内部类之间的区别?

我知道尽可能避免使用 public 内部类(如在这篇文章中所述)。

但据我所知,使用 protectedpublic 修饰符之间没有区别。

看看这个例子:

public class Foo1 {
 public Foo1() { }

 protected class InnerFoo {
  public InnerFoo() {
   super();
  }
 }
}

...

public class Foo2 extends Foo1 {
 public Foo2() {
  Foo1.InnerFoo innerFoo = new Foo1.InnerFoo();
 }
}

...

public class Bar {
 public Bar() {
  Foo1 foo1 = new Foo1();
  Foo1.InnerFoo innerFoo1 = foo1.new InnerFoo();

  Foo2 foo2 = new Foo2();
  Foo2.InnerFoo innerFoo2 = foo2.new InnerFoo();
 }
}

无论我将InnerFoo声明为protected还是public,所有这些都可以编译并且是有效的。

我错过了什么?请告诉我在使用protectedpublic时有区别的情况。

谢谢。

3个回答

23

protected 访问修饰符会限制访问权限,仅允许同一包中的类和其子类进行访问。

在本例中,publicprotected 具有相同的效果,因为它们位于同一包中。

如需了解更多关于访问修饰符的信息,请参阅控制类成员访问权限页面,该页面位于Java 教程网站上。


好的,我明白了。因为内部类就像封装类的成员一样,所以我一直在考虑受保护的成员。谢谢。 - bruno conde
1
@bruno conde:受保护的类就像受保护的成员一样。 - Michael Myers
换句话说,在Java中,“protected”无论应用于成员还是内部类,都与C++和C#不同。它授予同一包(命名空间)中其他类的访问权限。 - Qwertie
@Qwertie:有点晚了,但在Java中,protected允许访问同一包中的其他类、声明类和所有子类(无论是否在同一包中)。然而据我所知,在访问修饰符方面没有包层次结构。也就是说,以声明类的包名称为前缀的包中的类将无法访问。 - Newtopian

1

Java中的奇怪事情:

纯Java: 你不能从公共getter方法返回私有内部类

在JSP中: 你不能从公共getter方法返回非公共内部类


可以运行的Java演示:

public class ReturnInnerClass{
    public static void main(String []args){
        MyClass inst = new MyClass("[PROP_VAL]");
        System.out.println(

            inst.get().myProperty()

        );;    
    };;
};;

class MyClass{ 
    //:If JSP: MUST be public
    //:Pure Java: 
    //:     public,protected,no-access-modifier
    //:     Will all work.
    //:Private fails in both pure java & jsp.
    protected class Getters{
        public String 
        myProperty(){ return(my_property); }
    };;

    //:JSP EL can only access functions:
    private Getters _get;
    public  Getters  get(){ return _get; }

    private String 
    my_property;

    public MyClass(String my_property){
        super();
        this.my_property    = my_property;
        _get = new Getters();
    };;
};;

//:How to run this example:
//:  1: Put this code in file called: "ReturnInnerClass.java"
//:  2: Put ReturnInnerClass.java into it's own folder.
//:     ( Folder name does not matter.)
//:  3: Open the folder.
//:  4: Right-Click --> GitBashHere
//:  5: In command prompt within folder:
//:     5.1: javac ReturnInnerClass.java
//:     5.2: java  ReturnInnerClass
//:     ( javac: java compiler              )
//:     ( java : runs compiled java program )

//:  EXPECTED OUTPUT:
//:  [PROP_VAL]

对于JSP,只需将类代码放在文件夹中:com/myPackage/MyClass,并将“import com.myPackage.MyClass”作为源代码的第一行。然后使用此源代码创建一个新的.jsp页面:
<%@ taglib uri   ="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page import="com.myPackage.MyClass" %>
<%
    MyClass inst = new MyClass("[PROP_VALUE]");
    pageContext.setAttribute("my_inst", inst ); 
%><html lang="en"><body>
    ${ my_inst.get().myProperty() }
</body></html>

使用的技术栈: Java8 + Tomcat9


1

你可以将受保护的内部类视为受保护的成员,因此它只能被类、包和子类访问,而不能被外部访问。

此外,对于外部类,它只有两个访问修饰符。即public和package。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接