6

在 Java 中,通过将访问修饰符保留为默认值(空白),这些字段只能由同一包中的成员访问。但是,这并不能阻止其他人在同一个包中声明他们的类,然后从那里访问“默认”字段。

有没有办法在 Java 中使字段 C# 等效于internal. 也就是说,当我构建我的库(JAR 文件)时,其他人无法从 JAR 外部访问这些字段吗?即使在与我的课程相同的包中声明他们的课程时。

这是我在图书馆中的声明:

package com.my.package;
class MyRestrictedClass{
}



我试图阻止的是我的库的用户在他们的项目中使用我的 jar 添加到他们的构建路径中,例如:

package com.my.package; //Add their class to my package
public class DeveloperClass{
    public void main(){
        MyRestrictedClass foo = new MyRestrictedClass();
    }
}
4

2 回答 2

7

您可以密封包装。这可以防止人们将类添加到类路径中(尽管您仍然必须保护您的 jar)。

http://docs.oracle.com/javase/tutorial/deployment/jar/sealman.html

密封你的 jar 之后,你仍然可以编译一个声称在同一个包中的类,但是当你运行它时,它将无法运行:

Exception in thread "main" java.lang.SecurityException: sealing violation: can't seal package org.splore.so.access: already loaded
at java.net.URLClassLoader.getAndVerifyPackage(URLClassLoader.java:395)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:417)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.splore.so.access.AccessTestFromOtherPackage.main(AccessTestFromOtherPackage.java:5)
于 2013-11-04T16:45:35.487 回答
-1

您可能想尝试其他访问修饰符,例如“受保护”。但是:如果有人真的想访问您的方法,他/她可以使用反射并在运行时覆盖修饰符,使其可以根据需要使用。他们可以走得更远,例如删除最终标志等。因此,假设如果您使用适当的修饰符,没有人将能够访问您的类是不安全的。

我现在不知道,但也许有一个注释可以帮助您的库的用户理解,他们不应该使用您的类(您提供的公共 API 除外)。也许有类似@depriated 之类的东西,但我自己没有使用过。

于 2013-11-04T16:49:23.793 回答