Java相当于C#的“内部”

时间:2013-11-04 16:43:29

标签: c# java internal access-modifiers

在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();
    }
}

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:-1)

您可能想尝试其他访问修饰符,例如“protected”。 但是:如果有人真的想要访问您的方法,他/她可以使用反射并在运行时覆盖修改器,使其可用。它们可以更进一步,例如删除final-flag等。因此,假设如果使用适当的修饰符,没有人能够访问您的类,这是不安全的。

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

相关问题