【问题标题】:How can I access public member of private package class?如何访问私有包类的公共成员?
【发布时间】:2014-10-27 22:18:48
【问题描述】:

我是 Java 的新手,当时我正在阅读“Thinking in Java”。因此,当我试图理解“访问控制”一章时,我读到有可能访问 package private 类的 public 成员并且对此有点困惑.所以我决定检查这个语句,但是当我试图编译这样的代码时,我得到了一个错误。这是一个简单的例子:

PrivatePackageClass.java:

package simple.PrivatePackage;

class PrivatePackageClass {
    public static void print(Object obj) {
        System.out.println(obj);
    }
}

PublicAccessClass.java

package simple;

import simple.PrivatePackage.*;
import java.util.*;

public class PublicAccessClass {
    public static void main(String[] args) {
        PrivatePackageClass.print(Arrays.toString(args));
    }
}

这是错误的描述:

PublicAccessClass.java:8: 错误:
PrivatePackageClass 在 simple.PrivatePackage 中不公开;无法从外部包访问
PrivatePackageClass.print(Arrays.toString(args));

那么,我认为没有简单的可能性可以访问包私有类的公共成员吗?

UPD!谢谢大家,我知道如果两段代码都在同一个包中,那就没问题了。但我仍然对书中的陈述感到困惑。这是:

如前所述,如果您没有为类访问添加访问说明符,则默认为包访问。这意味着该类的对象可以由包中的任何其他类创建,但不能在包外创建。但是,如果该类的 static 成员是 public,则客户端程序员仍然可以访问该 static 成员,即使他们无法创建那个班级。

如果有人能解释我怎么可能,我将不胜感激。

【问题讨论】:

  • 我现在正在读这本书“Thinking Java”(2 年后第二次),遇到了你引用的这个奇怪的陈述:) 好像书中有错误,当然你不能甚至将包访问类导入到其他包中,更不用说访问它的任何成员了。

标签: java oop package member public


【解决方案1】:

我读过这本书 Think in Java (Fourth Edition)。我也对这种说法感到困惑。

有些情况可能与陈述不完全相符,但可以作为补充说明。

我不确定这些案例是否适用,感谢阅读,欢迎 cmets。

案例1包访问类public static main()方法可以使用调用命令行中的“java”命令,如第 169 页上的语句

即使程序中有很多类,也只有 main() 将调用在命令行上调用的类。所以在这种情况下, 当您说 java Detergent 时,将调用 Detergent.main()。但是你 也可以说 java Cleanser 调用 Cleanser.main( ),即使 Cleanser 不是公共类即使一个类有包 访问,公共 main() 是可访问的

例如在这个目录“testThinkingInJava\src\main\java\”中有一些文件(.java”和“.class”):

testMiscellaneous\Miscellaneous.java:

package testMiscellaneous;

class Miscellaneous {
    public static void main(String[] args) {
        System.out.println("public static void main(String[] args) called");
    }
}

testMiscellaneous/Miscellaneous.class(使用“javac”命令生成)

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package testMiscellaneous;

class Miscellaneous {
    Miscellaneous() {
    }

    public static void main(String[] var0) {
        System.out.println("public static void main(String[] args) called");
    }
}

运行此命令时:

java -classpath C:\projects\testThinkingInJava\src\main\java testMiscellaneous.Miscellaneous

你可以得到这样的输出:

PS C:\Users\pie> java -classpath C:\projects\testThinkingInJava\src\main\java testMiscellaneous.Miscellaneous
public static void main(String[] args) called
PS C:\Users\pie>

如您所见,Miscellaneous 类的可见性是包访问(在.java 和.class 文件中),并且调用了main 方法。

案例 2通过公共派生类调用方法。

例如 C:\projects\testThinkingInJava\src\main\java\testMiscellaneous\Miscellaneous.java

package testMiscellaneous;

class Miscellaneous {
    public static String staticMember = "staticMember";

    public static String staticMethod() {
        String s = "staticMethod";

        System.out.println("public static String staticMethod() called");

        return s;
    }

    public static void main(String[] args) {
        System.out.println("public static void main(String[] args) called");
    }
}

C:\projects\testThinkingInJava\src\main\java\testMiscellaneous\Miscellaneous2.java

package testMiscellaneous;

public class Miscellaneous2 extends Miscellaneous {
}

C:\projects\testThinkingInJava\src\main\java\testThinkingInJava\Application.java

package testThinkingInJava;

import testMiscellaneous.Miscellaneous2;

public class Application {
    String s = Miscellaneous2.staticMember;

    public static void main(String[] args) {
        Miscellaneous2 miscellaneous2 = new Miscellaneous2();

        String s2 = Miscellaneous2.staticMethod();

        System.out.println(s2);

        System.out.println(Miscellaneous2.staticMember);
    }
}

运行应用程序时,可以得到输出:

public static String staticMethod() called
staticMethod
staticMember

如你所见:

1类Miscellaneous是包访问;

2 类 Miscellaneous2 简单地从 Miscellaneous 派生,但被授予公共访问权限;

3类Application驻留在另一个包中,可以通过Miscellaneous2访问Miscellaneous的方法。

【讨论】:

    【解决方案2】:

    PublicAccessClass 具有包私有访问权限,因此只有其包中的类才能访问它。

    simple.PublicAccessClasssimple.PrivatePackage.PublicAccessClass 不在同一个包中,因此PublicAccessClass 无法访问它。如果它们在同一个包中,您的代码就可以工作。

    【讨论】:

      【解决方案3】:

      这将帮助您理解在 java 中访问成员背后的概念

      花点时间读出来

      http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

      在你的情况下 您无法访问方法,因为它未在其包中声明为 public

      默认成员只能在同一个包中访问。

      【讨论】:

        【解决方案4】:

        不,你不能。在我看来,您现在将包的成员(即类)与类的方法混淆了。

        【讨论】:

          【解决方案5】:

          您的类 PrivatePackageClass 必须以访问修饰符 public 开头,以便在当前文件之外可以访问它

          要回答您的第二个查询,静态成员/方法不需要创建要访问的类的对象。静态成员属于一个类而不是特定于一个对象

          【讨论】:

            【解决方案6】:

            Public members in package private class

            包私有类可以拥有具有公共或受保护访问权限的成员,但是,这样的成员不能在包外访问。

            “如前所述,如果不为类访问放置访问说明符,则默认为包访问。这意味着该类的对象可以由包中的任何其他类创建,但不能在包之外创建(请记住,同一目录中没有显式包声明的所有文件都隐含地属于该目录的默认包。)但是,如果该类的静态成员是公共的,客户端程序员仍然可以访问那个静态成员,即使他们不能创建那个 class.package 的对象。”

            我认为段落中的最后一句话是单例。

            【讨论】:

              猜你喜欢
              • 2013-10-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-04-08
              • 2018-05-10
              相关资源
              最近更新 更多