静态修饰符会改变java中类成员的访问级别吗?
Posted
技术标签:
【中文标题】静态修饰符会改变java中类成员的访问级别吗?【英文标题】:Does static modifier change the access level of a class member in java? 【发布时间】:2017-09-06 21:20:02 【问题描述】:我正在阅读有关 Java 7 认证的 OCA 和 OCP 的书,我正在尝试使用 Java 8 进行本书的练习,我注意到一些连线。
我有 Class1 类如下:
package cert;
public class Class1
protected static void importantMethod()
System.out.println("importantMethod() method of Class1 class TEST \n");
importantMethod() 方法的修饰符是 protected static 并且包是 cert 如您所见,如书中所述我希望另一个包中的另一个类,在我的例子中显示如下 Class2,只能通过继承访问 importantMethod() 方法,但事实证明,来自 Class2 我也可以通过 Class1 的实例访问 importantMethod() 方法。
Class2 类:
package exam;
import cert.Class1;
class Class2 extends Class1
public static void main(String[] args)
Class1 c1 = new Class1();
c1.importantMethod();
如果我从 Class1 中删除 static 修饰符,则在尝试从 importantMethod() 方法访问时会出现预期错误>Class2:
exam\Class2.java:7: error: importantMethod() has protected access in Class1
c1.importantMethod();
^
我的问题是,非访问修饰符会改变类成员的访问级别吗?
【问题讨论】:
"Class1 的修饰符是protected static"...你的问题清楚地显示为public
@cricket_007 他应该指的是方法“importantMethod”的修饰符。
相关:***.com/questions/24289070/…
静态成员是类的属性,非静态成员是对象或实例的属性。快速回答是否定的,static
不会更改访问级别,而是更改访问的类型。
嗨@DrewKennedy,所以我可以通过Class1的实例访问importantMethod而不是作为继承的成员对吗?
【参考方案1】:
事实证明,我可以从 Class2 中通过 Class1 的实例访问 importantMethod() 方法
您不需要实例来调用静态方法。 Class1.importantMethod()
工作正常。如果您删除 static
,它不会,这就是您所看到的。
如果我从 Class1 中删除静态修饰符,它会给出预期的错误
因为你在不同的包中,而不是像这样通过继承调用方法
package exam;
import cert.Class1;
public class Class2 extends Class1
public static void main(String[] args)
new Class2().importantMethod();
【讨论】:
嗨@cricket_007,你说你不需要实例来调用静态方法。这就是为什么它起作用的原因。,但它不应该起作用,因为我仍然在不同的包中并且 importantMethod() 方法具有受保护的访问修饰符,这就是为什么我问为什么它工作。无论如何它都受到保护,我认为它是否是静态的并不重要,因为静态是非访问修饰符对吗?反正我不能打电话了c1.importantMethod()
是静态方法时不正确。 Class1.importantMethod()
是指静态方法的方式,protected
不会影响这一点,我不认为
但是 c1.importantMethod() 有效。如果这不正确,我不应该在这种情况下犯错吗?
这是一个编译器警告。它在语法上不正确。您永远不需要实例来调用静态方法。这是我唯一的观点
不,你不是通过实例访问它,它只有一个副本,因为它是一个静态成员,你需要回去重新阅读你的学习资料,因为你没有理解它正确。【参考方案2】:
一切都很好 - 这就是 protected
访问的方式。在JLS 6.6.2.1中指定:
让
C
成为声明受保护成员的类。仅允许在C
的子类S
的主体内访问。另外,如果
[与Id
表示一个实例字段或实例方法,那么:Id
无关的内容不表示实例字段或实例方法]
您的代码在C
的子类S
的主体内(其中S
是Class2
,C
是Class1
)所以没关系。 p>
【讨论】:
嗨@JonSkeet,这本书的这一部分让我感到困惑:这使得认证包内的所有其他类都可以访问该变量,以及** inheritable 任何人包外的子类**。最后,我们看到包外的子类不能使用超类引用来访问受保护的成员。 对于包外的子类,只能通过继承访问受保护的成员。谢谢你的回答。 @ArberHoxha:嗯,这只是说同一件事的一种不太清楚的方式。 “仅通过继承”被用作“仅在 C 的子类 S 的主体内”及其后部分的简写。 请看一下这张图片第38页和第39页之间的例子:dropbox.com/s/4gdl6ry939285gi/Protected.PNG?dl=0 @ArberHoxha:是的,这可以通过“无关内容”中的规则来解释,因为它显示了一个实例字段。您的问题显示了一个静态字段。真的,只需阅读我提到的规范部分。 @ArberHoxha:不,根据语言规范,编译器的行为是正确的。不幸的是,您使用的这本书只是使用了过于简单化的术语。以上是关于静态修饰符会改变java中类成员的访问级别吗?的主要内容,如果未能解决你的问题,请参考以下文章