【问题标题】:Java's equivalent to C#'s "internal" [duplicate]Java 相当于 C# 的“内部”[重复]
【发布时间】:2013-11-15 08:38:49
【问题描述】:

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

【问题讨论】:

    标签: c# java internal access-modifiers


    【解决方案1】:

    您可以密封包裹。这会阻止人们将类添加到类路径中(尽管您仍然必须保护您的 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)
    

    【讨论】:

    • 我试过了。但我仍然可以从 jar 外部访问我的“默认”类。我检查了我的清单,它确实是密封的。
    • 您确定您的“默认”类定义正确吗?
    • 我想:class MyClass{} 从将 jar 添加到其构建路径的项目中,我仍然可以这样做:MyClass myClass = new MyClass();。当然,只有当我声明调用代码在同一个包中时。
    • 我刚刚看到您的编辑,我们几乎在同一页面,但不完全一致。我已经编辑了我的问题。
    • 看看我编辑的问题。您的示例和我的示例之间的唯一区别是开发人员在与我的示例相同的包中声明了他们的类。
    【解决方案2】:

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

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

    【讨论】:

    • 如果投反对票的人有耐心解释他们投反对票的原因会很好......
    • 不是我,但我的猜测是,否决票是因为 protected 实际上比(默认)更容易访问,而且您的答案并没有真正给出解决方案,而是猜测。
    猜你喜欢
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    相关资源
    最近更新 更多