5
class Orange{

    Orange(){
    }

}

在类前面和构造函数前面使用修饰符(在本例中为 package-private)有什么区别?我认为构造函数前面的修饰符意味着它可以实例化类的实例Orange。但是类前面的修饰符呢?

4

8 回答 8

15

首先,由 3 个访问修饰符创建了 4 个访问级别。

  1. 公共 - 随处可访问
  2. 受保护 - 可在同一个包和儿童中访问
  3. 默认 - 只能在同一个包中访问
  4. private - 只能在同一个类中访问。

您是正确的-构造函数级别的修饰符与类的实例化直接相关。

Class 级别的修饰符决定了 Class 的可访问性。

于 2013-05-24T04:10:30.607 回答
5

首先,为了消除任何担忧,您提供的代码完全有效的 Java 语法。

实际上,您已经创建了一个只能由默认包中的其他类实例化/使用的类。如果您在包中定义它(例如),它也可以工作,package foo;因为只有包中的类foo才能看到这个类)。

现在,问题的症结所在。

有多种方法可以控制对字段和成员的访问。他们每个人都做不同的事情。

  • private能见度是最不可见的。只有定义类可以访问该字段。

  • 没有修饰符,或者package private是第二个最不可见的。定义类包中的所有类都可以访问该字段,但子类和世界其他地方不能。

  • protected是第二个最明显的。只有其他类被禁止访问该字段。

  • public是最明显的。 一切都可以访问该领域。

类级别的修饰符变得有趣。这来自Java 语言规范,§8.1.1

访问修饰符public(第 6.6 节)仅适用于顶级类(第 7.6 节)和成员类(第 8.5 节),不适用于本地类(第 14.3 节)或匿名类(第 15.9.5 节)。

访问修饰符protectedprivate(第 6.6 节)仅适用于直接封闭类或枚举声明(第 8.5 节)中的成员类。

修饰符 static 仅适用于成员类(第 8.5.1 节),不适用于顶级或本地或匿名类。

如果同一个修饰符在类声明中出现多次,则为编译时错误。

如果两个或多个(不同的)类修饰符出现在一个类声明中,那么尽管不是必需的,但习惯上它们出现的顺序与上面的产生式中显示的顺序一致ClassModifier

一般来说,类声明看起来像这样:

ClassDeclaration:
    NormalClassDeclaration
    EnumDeclaration

NormalClassDeclaration:
    ClassModifiers(opt) class Identifier TypeParameters(opt)
                        Super(opt) Interfaces(opt) ClassBody

带有 (opt) 的任何内容都被认为是可选的。

那么,这意味着什么?

  • JLS 要求类不需要 [class] 修饰符。
  • JLS 规定,如果存在 [class] 修饰符,则它遵循以下规则之一:
    • 如果修饰符是public,那么它只适用于顶级类和成员类。
    • 如果修饰符是protectedor private,那么它仅适用于直接封闭类或枚举中的成员类。
    • 修饰符可能会出现static,但仅适用于成员类。

构造函数有类似的规则集。

ConstructorDeclaration:
    ConstructorModifiers(opt) ConstructorDeclarator
                                Throws(opt) ConstructorBody

ConstructorDeclarator:
    TypeParameters(opt) SimpleTypeName ( FormalParameterList(opt) )

同样,这分解为:

  • JLS 要求构造函数不需要 [constructor] 修饰符。
  • JLS 要求构造函数修饰符不能包含abstract, static, final, native, strictfp, 或synchronized
  • JLS 规定,如果没有为普通类的构造函数指定访问修饰符,则构造函数具有默认访问权限(第 8.8.3 节,强调我的)。
于 2013-05-24T05:44:31.243 回答
3

您只能在 Java 中声明公共或默认类(仅在顶级类的情况下),这些修饰符决定了类的可访问性。

我还建议您查看“为什么类或接口不能接收私有或受保护的访问修饰符?

现在就构造函数而言,当没有显式定义访问修饰符时,构造函数将具有默认类型的访问控制。因此,此构造函数将具有包级别访问权限。只有那些在该包中定义为具有此默认构造函数的类的类才能访问它。请参阅“默认情况下 Java 构造函数不是公开的吗?

如果构造函数是私有的,那么只有该类中的代码可以访问它。为了更好地理解修饰符,您需要查看“ Java 中的访问修饰符

于 2013-05-24T04:03:51.440 回答
1

类的修饰符定义谁可以访问该类。例如public,任何包中的类都可以访问类,如果没有编写修饰符,则该类只能被同一个包中的类访问。

构造函数、方法和字段的修饰符含义相同。但是private,并protected有更多的意义。Private 只能从当前类访问。不受其子类的保护,也不受同一包中的类的保护。

关于你关于构造函数的问题。类可以有多个构造函数。其中一些可以是私有的,而另一些可以是公开的。你是对的,如果类是包保护的,那么公开构造函数是没有意义的:无论如何,包外的任何人都不能调用这个类。

这就像为抽象类编写公共构造函数一样。由于抽象类本身不能被实例化,它的构造函数应该是protected或者private尽管编译器不关心这一点。

顺便说一句,使用默认包不常用,也不推荐使用。

于 2013-05-24T04:03:01.780 回答
1

关卡修饰符的用途类型class

http://javapapers.com/core-java/access-modifiers-in-java-explain/

关卡修饰符的用途类型constructor

http://www.careercup.com/question?id=296844#commentThread302715

于 2013-05-24T04:20:03.040 回答
0

访问修饰符:

  • 公开 - {可以访问项目中的任何位置}
  • Private - {只能在班级内访问}
  • 受保护 - {可以在包和子类中访问}
  • 默认 - {可以在包内访问}

非访问修饰符:

  • 静态 - {用于创建类变量和方法}
  • Final - {用于创建最终变量和方法}
  • Abstract - {用于创建抽象方法和类}
  • 同步 - {用于线程}

在此链接中对上述修饰符进行了一些简要讨论。参考它以获得更好的理解。

于 2014-04-21T05:08:25.337 回答
0

类修饰符的工作方式类似于方法修饰符。公共,私人,最终,抽象等工作。

Public 允许任何包中的类访问该类及其方法。

没有修饰符只允许从它定义的包中访问类。

Private 将阻止所有访问(如果与顶级类一起使用,则没有意义)。

抽象类允许您创建从(抽象)类派生的子类。例如,您可以创建一个抽象形状类并让一个矩形类扩展形状,继承它的所有方法、变量,并强制它定义任何抽象方法。

于 2013-05-24T04:05:32.683 回答
0

我发现Java中最好的可见性级别是可见性,default可见性,因为如果测试与主类放在同一个包中,它使单元测试类能够访问所有方法。

由于您可以省略可见性声明,因此包可见性也更短,因此样板文件更少。

第二好的可见性级别是protected,因为在某些情况下,您可以将测试类创建为主类的子类。但是,如前所述,如果您正确使用包,包的可见性在大多数情况下会更好。

第三,通常如果您运行 Sonar 并对大型项目进行代码审查和静态分析,我发现通常 80% 的方法是public,而 20% 是private/ protected。因此,使用私有或受保护方法的主要思想是通过绕过访问器来保护数据/属性不被访问。无论如何,大多数方法通常都是公开的。

最无用的可见性级别(但不幸的是常用)是private因为它无法测试(不使用反射和修改其他东西的可见性)。此外,private禁止在子类中重用代码,这是首先使用面向对象范式的主要思想,因此应该避免。出于同样的原因final,在大多数情况下应避免使用关键字。

因此,我发现您的示例是如何定义可见性级别的最佳实践,除了您的构造函数不是公共的:)。但是,您缺少包声明和单元测试。

于 2017-11-09T23:25:34.550 回答