简体   繁体   English

如何访问私有包类的公共成员?

[英]How can I access public member of private package class?

I am pretty novice in Java and I'am reading "Thinking in Java" at that moment. 我是Java的新手,当时正在阅读“用Java思考”。 So while I was trying to understand "Access Control" chapter I've read that there is a possibility to acces public member of package private class and was a bit confused about it. 因此,当我尝试理解“访问控制”一章时,我已经读到有可能加入包私有类的公共成员,对此有些困惑。 So I've decided to check this statement, but when I tried to compile such code I got an error. 因此,我决定检查此语句,但是当我尝试编译此类代码时,出现错误。 Here's a simple example: 这是一个简单的例子:

PrivatePackageClass.java: PrivatePackageClass.java:

package simple.PrivatePackage;

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

PublicAccessClass.java PublicAccessClass.java

package simple;

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

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

That is the description of error: 那就是错误的描述:

PublicAccessClass.java:8: error : PublicAccessClass.java:8: 错误
PrivatePackageClass is not public in simple.PrivatePackage; PrivatePackageClass在simple.PrivatePackage中不是公共的; cannot be accessed from outside package 无法从外部包访问
PrivatePackageClass.print(Arrays.toString(args)); PrivatePackageClass.print(Arrays.toString(参数));

So am I right that there's no simple possibility to access public members of package-private classes? 因此,我对访问私有包类的公共成员没有简单的可能性吗?

UPD! UPD! Thank you all, I know that if both pieces of code were in the same package it will be Ok. 谢谢大家,我知道,如果这两段代码都在同一个程序包中,那就可以了。 But I am still confusing about statement in the book. 但是我仍然对书中的陈述感到困惑。 Here it is: 这里是:

As previously mentioned, if you don't put an access specifier for class access, it defaults to package access. 如前所述,如果您没有为类访问添加访问说明符,则默认为包访问。 This means that an object of that class can be created by any other class in the package, but not outside the package. 这意味着该类的对象可以由包中的任何其他类创建,但不能在包外部创建。 However, if a static member of that class is public , the client programmer can still access that static member even though they cannot create an object of that class. 但是,如果该类的静态成员是public ,则客户端程序员即使无法创建该类的对象,仍然可以访问该静态成员。

I would be grateful if somebody could explain me how could it be. 如果有人能解释一下我将如何,我将不胜感激。

PublicAccessClass has package private access, so only classes within its package can access it. PublicAccessClass具有包私有访问权限,因此只有其包中的类才能访问它。

simple.PublicAccessClass is not in the same package as simple.PrivatePackage.PublicAccessClass , and therefore PublicAccessClass can't access it. simple.PublicAccessClass不在同一个包simple.PrivatePackage.PublicAccessClass ,因此PublicAccessClass不能访问它。 If they were in the same package, your code would work. 如果它们在同一软件包中,则您的代码将起作用。

this will help you in understanding the concept behind accessing of members in java 这将帮助您理解java中访问成员背后的概念

take a moment to read it out 花一点时间读出来

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

In your case you cant access method as it is not declared public in its package 在您的情况下,您无法访问方法,因为该方法未在其包中声明为公共方法

and default members can only be accessed within same package. 和默认成员只能在同一软件包中访问。

No, you can't. 不,你不能。 Seems to me that you're now confusing the member of a package, which is a class, to the method of a class. 在我看来,您现在将包(即类)的成员与类的方法混淆了。

Your class PrivatePackageClass must be preceded by the access modifier public for it to be accessible outside the current file 您的类PrivatePackageClass必须带有公共访问修饰符,才能在当前文件外部进行访问

To answer your second query static member/methods don't need to create an object of the class to access. 要回答第二个查询,静态成员/方法不需要创建要访问的类的对象。 Static members belong to a class and not specific to an object 静态成员属于一个类,而不特定于一个对象

Public members in package private class 私人课程包中的公共成员

package private class can have members with public or protected access, however, such a member can not be accessed outside the package. 包私有类可以具有具有公共或受保护访问权的成员,但是,不能在包外部访问该成员。

"As previously mentioned, if you don't put an access specifier for class access, it defaults to package access. This means that an object of that class can be created by any other class in the package, but not outside the package. (Remember, all the files within the same directory that don't have explicit package declarations are implicitly part of the default package for that directory.) However, if a static member of that class is public, the client programmer can still access that static member even though they cannot create an object of that class.package." “如前所述,如果不为类访问添加访问说明,则默认为包访问。这意味着该类的对象可以由包中的任何其他类创建,但不能在包外部创建。请记住,同一目录中所有没有显式包声明的文件都隐式属于该目录的默认包。)但是,如果该类的静态成员是公共的,则客户端程序员仍可以访问该静态成员。即使他们无法创建该class.package的对象。”

I think the last sentence in the paragraph means singleton. 我认为该段的最后一句表示单例。

I have read this book Think in Java (Fourth Edition). 我已经读过《用Java思考(第四版)》这本书。 I am also confusing about this statement. 我对此说法也感到困惑。

There are some cases, which may be not exactly match the statement, but may be as a supplementary explanation. 在某些情况下,可能与声明不完全匹配,但可以作为补充说明。

I am not sure those cases is applicable or not, thanks for reading and comments welcomed. 我不确定这些情况是否适用,感谢您的阅读和评论。

Case 1 : The public static main() method of a package access class can be invoked using "java" command on the command line, like the statement on page 169 : 情况1可以在命令行上使用“ java”命令 来调用 包访问类public static main()方法 ,如第169页上的语句:

Even if you have a lot of classes in a program, only the main( ) for the class invoked on the command line will be called. 即使程序中有很多类,也只会调用在命令行上调用的类的main()。 So in this case, when you say java Detergent, Detergent.main( ) will be called. 因此,在这种情况下,当您说java Detergent时,将调用Detergent.main()。 But you can also say java Cleanser to invoke Cleanser.main( ), even though Cleanser is not a public class . 但是, 即使Cleanser不是公共类 ,您也可以说java Cleanser调用 Cleanser.main()。 Even if a class has package access, a public main() is accessible . 即使类具有包访问权限,也可以访问公共main()

eg There are some files(.java" and ".class") in this directory "testThinkingInJava\\src\\main\\java\\": 例如,在此目录“ testThinkingInJava \\ src \\ main \\ java \\”中有一些文件(.java”和“ .class”):

testMiscellaneous\\Miscellaneous.java: 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 (generated using "javac" command) 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");
    }
}

When run this command: 运行此命令时:

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

you can get the output like this: 您可以这样获得输出:

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>

As you can see that the visibility of Miscellaneous class is package access (both in .java and .class file), and the main method was invoked. 如您所见,Miscellaneous类的可见性是程序包访问(在.java和.class文件中),并且调用了main方法。

Case 2 : Invoke the method via a public derived class . 情况2通过公共派生类调用该方法。

eg C:\\projects\\testThinkingInJava\\src\\main\\java\\testMiscellaneous\\Miscellaneous.java 例如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 C:\\项目\\ testThinkingInJava的\\ src \\主\\ java的\\ testMiscellaneous \\ Miscellaneous2.java

package testMiscellaneous;

public class Miscellaneous2 extends Miscellaneous {
}

C:\\projects\\testThinkingInJava\\src\\main\\java\\testThinkingInJava\\Application.java C:\\项目\\ testThinkingInJava的\\ src \\主\\ 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);
    }
}

When run the application, you can get the output: 运行应用程序时,可以获得输出:

public static String staticMethod() called
staticMethod
staticMember

As you can see: 如你看到的:

1 class Miscellaneous is package access; 杂项是一类。

2 class Miscellaneous2 simply derived from Miscellaneous, but given public access; 2类Miscellaneous2简单地从Miscellaneous派生而来,但具有公共访问权限;

3 class Application resides in another package, and can access method of Miscellaneous, via Miscellaneous2. 3类Application驻留在另一个程序包中,并且可以通过Miscellaneous2访问Miscellaneous的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM