有没有办法将java函数导出到库中的其他包,但不能导出到库的用户?

时间:2012-07-04 05:01:19

标签: java visibility

所以,这是一个例子。我在包HTTP中有一个库。我定义了例如库的子部分。包HTTP.TCPProtocol。现在我想从HTTP包中使用TCPProtocol,这意味着我必须公开TCPProtocol功能。同时,不应将此功能导出到库的用户。

我该怎么做?我不想把我的整个库推到一个包中,因为我觉得单独的子包确实使代码更加结构化,并且在eclipse中导航更容易。但浏览时,我找不到在项目中公开函数的方法,但是不能将它们导出到我的项目之外。

编辑:鉴于我能够提出一个更好的例子,我正在更新OP。

3 个答案:

答案 0 :(得分:2)

一种简单的方法是将您的“实用程序”方法列入白名单,以便它们只接受某种类型的调用者实例。

package gameengine;

interface Whitelisted {} // marker

然后你的方法:

public void myMethod(Whitelisted caller, String arg)

并调用:

package gameengine.network;

class Foo implements Whitelisted {
...
Someclass.myMethod(this, "foo");

答案 1 :(得分:1)

如果没有看到您的依赖关系,社区可以给您的唯一真正建议就是重构您的代码。如果您的网络包中的某些内容需要了解您的游戏引擎,那么您似乎有一个漏洞的抽象。很难说没有看到你的代码。

答案 2 :(得分:1)

检查来电者的课程以锁定所有不受欢迎的来电者。调用者的类可以从堆栈跟踪中获得。在下面的示例中,只有Bar的实例将触发system.out.println,所有其他实例都将获得异常。您甚至可以通过这种方式进行包级检查。确保所有允许的调用者类方法都不公开,或者他们可以间接调用doSomething方法。您甚至可以通过进一步检查堆栈跟踪来进行更深入的检查。

请注意,熟练的开发者可以绕过你在这件事上尝试做的任何事情。没有解决方案真正“安全”。

package one.two;

import one.Bar;

public class Foo {

    public void doSomething() {

        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        StackTraceElement stackTraceElement = stackTrace[2];
        String className = stackTraceElement.getClassName();

        if (Bar.class.getName().equals(className)) {
            System.out.println("jay!");
        } else {
            throw new RuntimeException("not allowed");
        }

    }
}

package one;

import one.two.Foo;

public class Bar {

    void makeCall() {
        new Foo().doSomething();
    }

    public static void main(String[] args) {
        new Bar().makeCall();
    }

}