4

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

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

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

4

3 回答 3

2

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

package gameengine;

interface Whitelisted {} // marker

然后你的方法:

public void myMethod(Whitelisted caller, String arg)

并调用:

package gameengine.network;

class Foo implements Whitelisted {
...
Someclass.myMethod(this, "foo");
于 2012-07-04T05:19:37.477 回答
1

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

于 2012-07-04T05:19:36.823 回答
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();
    }

}
于 2012-07-04T07:38:25.017 回答