Java protected 修饰符未按预期工作

发布于 2024-08-24 00:36:52 字数 1362 浏览 7 评论 0原文

我有以下两个文件:

Fruit.java:

package superClass;

public class Fruit { 
 protected static void printName() {
  System.out.println("My name is Khan");
 }

}

Apple.java:

package food;

import superClass.*;

public class Apple  {
 public static void main(String[] args) {
  int i, j;
  for(i = 0; i < 5; i++) {
   for(j = 0; j < i; j++) {
    System.out.print("*");
   }
   System.out.println();
  }
  printName(); // Call inherited member - NO ERROR, expected

  Fruit f = new Fruit();
  f.printName(); // Call instantiated member - ERROR, expected
 }

}

正如预期的那样,我无法从 Apple 类访问受保护的方法 printName,因为它们驻留在不同的包中。我收到以下错误:

printName() has protected access in superClass.Fruit

完全正确。但是,如果我按如下方式从 superClass 类继承,则不会收到任何错误!

package food;

import superClass.*;

public class Apple extends Fruit {
 public static void main(String[] args) {
  int i, j;
  for(i = 0; i < 5; i++) {
   for(j = 0; j < i; j++) {
   System.out.print("*");
   }
   System.out.println();
 }
  printName(); // Call inherited member - NO ERROR, expected

  Fruit f = new Fruit();
  f.printName(); // Call instantiated member - NO ERROR, WHAT????
 }
}

为什么它允许我通过引用访问不同包中另一个类的受保护成员?这应该是非法访问,不是吗?

我很困惑!请有人帮忙。

该代码是使用 Java 1.6.0_18 编译的。

I have the following two files:

Fruit.java:

package superClass;

public class Fruit { 
 protected static void printName() {
  System.out.println("My name is Khan");
 }

}

Apple.java:

package food;

import superClass.*;

public class Apple  {
 public static void main(String[] args) {
  int i, j;
  for(i = 0; i < 5; i++) {
   for(j = 0; j < i; j++) {
    System.out.print("*");
   }
   System.out.println();
  }
  printName(); // Call inherited member - NO ERROR, expected

  Fruit f = new Fruit();
  f.printName(); // Call instantiated member - ERROR, expected
 }

}

As expected, I do not have access to the protected method printName from the class Apple as they reside in different packages. I get the following error:

printName() has protected access in superClass.Fruit

Perfectly correct. But if I inherit from the class superClass as follows I do not get any error!

package food;

import superClass.*;

public class Apple extends Fruit {
 public static void main(String[] args) {
  int i, j;
  for(i = 0; i < 5; i++) {
   for(j = 0; j < i; j++) {
   System.out.print("*");
   }
   System.out.println();
 }
  printName(); // Call inherited member - NO ERROR, expected

  Fruit f = new Fruit();
  f.printName(); // Call instantiated member - NO ERROR, WHAT????
 }
}

Why is it allowing me to access the protected member of another class in a different package by reference? This is supposed to be an illegal access, is it not?

I am confused! Someone please help.

The code was compiled using Java 1.6.0_18.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

草莓味的萝莉 2024-08-31 00:36:52

您观察到的行为是因为 printName 是静态的。 protected 修饰符提供了子类中该方法的可见性,但是如果该方法是非静态的,则只能通过子类的实例调用该方法(您提出的问题“如果我如下从类 superClass 继承,我不会收到任何错误!”)。 JLS 第 6.6.2.1 节简洁地定义了这一点。

The behavior you observe is because of the fact that printName is static. The protected modifier provides visibility of that method in the sub-class but if the method is non-static, invocation of that method is possible only through the instance of a sub-class (the concern you were raising "if I inherit from the class superClass as follows I do not get any error!"). The JLS section 6.6.2.1 defines this succinctly.

如若梦似彩虹 2024-08-31 00:36:52

protected 修饰符允许在继承的类中进行访问。如果您需要限制仅访问某些包中的类,则需要一个“package”修饰符,它只是一个空修饰符,即编写如下方法:

静态无效 printName()

它将具有包可见性。

protected modifier allows access in inherited classes. If you need to restrict access to classes only in certain package you need a "package" modifier, which is just an empty modifier, i.e. write method like this:

static void printName()

and it will have the package visibility.

违心° 2024-08-31 00:36:52

这是受保护的访问的定义:受保护的成员可以从子类访问,无论其位于不同的包中。

这里引用了Java的访问修饰符

注意:在Java中,约定是使用小写的包名称,即superClass不遵守此约定。您可能会被这个困扰 - 特别是如果您在文件和目录名区分大小写的 *nix 平台上进行开发。

This is the definition of protected access: protected members are accessible from subclasses, regardless of being in a different package.

Here is a reference to the access modifiers of Java.

Note: in Java, the convention is to have lowercase package names, i.e. superClass is not adhering to this convention. You might be bitten by this - especially if you are developing on *nix platforms where file and directory names are case sensitive.

苏辞 2024-08-31 00:36:52

超类的受保护成员可以从子类访问,即使超类位于另一个包中,但我们可以通过引用使用受保护成员的类来使用,因为此时该类是受保护成员的所有者。
假设

com.pack1 class A { protected int i;}
com.pack2 class D { System.out.println(i); System.out.println(a1.i); }

i中的受保护成员是完美的,但a1.i不完美,给出错误。
在 D 类中,我们可以通过 d 的引用而不是 A 类的引用来使用受保护的成员

The protected members of the superclass are accessible from the subclass, even if the superclass is in another package but we can use by reference of that class in which protected member is used because at this time that class is owner of protected member.
Suppose protected member in

com.pack1 class A { protected int i;}
com.pack2 class D { System.out.println(i); System.out.println(a1.i); }

i is perfect but a1.i is not perfect, give error.
In class D we can use protected member by reference of d not reference of class A

知你几分 2024-08-31 00:36:52

即使超类位于另一个包中,子类也可以访问超类的受保护成员。请参阅本页的第二部分和随附的表格/图表:

http ://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

The protected members of the superclass are accessible from the subclass, even if the superclass is in another package. See the second part of this page and accompanying table/diagram:

http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

空城之時有危險 2024-08-31 00:36:52

事情是这样的,当你说

printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - NO ERROR, WHAT????

记住 printName 是一个静态方法,所以即使编译器接受这种形式,

f.printName();

真正的形式也永远是

Fruit.printName(); // protected accesor allows the use of the method
Apple.printName(); // or just
printName(); // at the end everything is the same to this call

所以最后你得到了继承的静态方法,你只是对如何静态感到困惑方法有效,它们是类方法而不是实例,即使编译器不会抱怨编写表单

f.printName();

内部发生的真正事情是类访问。但可以肯定的是,编译器会给出与此类似的警告:

Fruit 类型的静态方法 printName() 应该以静态方式访问

Here is the thing, when you said

printName(); // Call inherited member - NO ERROR, expected
Fruit f = new Fruit();
f.printName(); // Call instantiated member - NO ERROR, WHAT????

keep in mind that printName is a static method, so even if the compiler accepts the form

f.printName();

The real form will always be

Fruit.printName(); // protected accesor allows the use of the method
Apple.printName(); // or just
printName(); // at the end everything is the same to this call

So at the end you get the static method inherited, you are just confused about how static methods works, they are class methods not instance, even if the compiler does not complain about writing the form

f.printName();

The real thing happening inside is class access. But is sure the compiler gives a warning similar to this:

The static method printName() from the type Fruit should be accessed in a static way

挖个坑埋了你 2024-08-31 00:36:52

您是否将 protected 与默认(又名包)修饰符混淆了?后者限制对同一包的成员的访问。

Protected 限制对包成员和从相关类继承的类的访问。

请参阅 http://java.sun.com /docs/books/jls/second_edition/html/names.doc.html#62587 了解详细信息

Are you confusing protected with the default (aka package) modifier? The later restricts access to members of the same package.

Protected restricts access to members of the package and classes inheriting from the class in question.

See http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#62587 for details

爱冒险 2024-08-31 00:36:52

是的,很好,您没有收到任何错误...这可能违反了 Java 语言规范或错误...无论如何,这是对的。这就是 protected 访问修饰符的定义。 Protected 类似于类成员可从外部或其他类访问的中间级别。我想这是私人和公共之间的事情。受保护的类成员可以(从类的子类)和(从其他类访问,只要它们属于同一个包)。只是一个想法!

Aye, dat's good that you did not get any error... that could have been a violation in the Java language specification or a bug... Anyway, that's right. that's the definition of protected access modifier. Protected is a like an intermediate level of class members' accessibility from the outside or from other classes. that's between private and public i suppose. protected class members are accessible ( from subclasses of a class ) and (from other classes as long as they belong to the same package). just a thought!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文