我需要有一个可以从我的 API 中的任何位置访问但不能从使用 API 的应用程序访问的 java 方法

Posted

技术标签:

【中文标题】我需要有一个可以从我的 API 中的任何位置访问但不能从使用 API 的应用程序访问的 java 方法【英文标题】:I need to have a java method that can be accessed from anywhere within my API but cannot be accessed from the application using the API 【发布时间】:2014-07-20 15:48:57 【问题描述】:

我正在开发一个 java API。在我的开发过程中,我一直面临以下问题:

我在两个不同的包中有两个类。包 x 中的 A 类,包 y 中的 B 类。我需要类 A 来访问类 B 中定义的方法 M。因此,应该用于方法 M 的修饰符是 public。但是,我不想让将在他/她的 java 应用程序中使用我的 API 的开发人员访问方法 M。问题是方法 M 有我提到的 public 修饰符,因此任何人都可以访问它在 API 内或从 API 外。同时,如果我将方法 M 的修饰符级别降低到 protectedprivate,类 A 将无法访问方法 M,因为它属于不同的包。我怎么解决这个问题?将 A 和 B 放在同一个包中是我唯一的解决方案吗?

【问题讨论】:

客户能否访问课堂B中的其他内容? 如果您需要类似的东西,您很可能应该重新设计您的代码结构。没有办法实现您正在寻找的东西。不幸的是,它有点过于抽象,无法给出更好的建议,它可能更适合编程。se 不幸的是,没有语言级别的结构可以完全满足您的需求。根据其他人调用M 的糟糕程度,您可以做的一件事是使用“不供外部消费”记录它,例如com.sun 包。 你可以用 OSGi 做到这一点,但它有异味。 【参考方案1】:

创建一个接口并仅将其公开给公众,隐藏您的实现。例如:

我的实现(比如说,application.jar):

public class Test implements TestInterface 
    public void somePrivateStuff()  

    public void somePublicStuff()  

亲爱的,这是我的 API(例如,publicAPI.jar):

public interface TestInterface 
    public void somePublicStuff();

其他开发人员会针对您的 publicAPI.jar 进行编译。运行时实现将来自您的 application.jar。

【讨论】:

这就是我的想法。只有当最终用户不需要自己构建类时才有效,当然工厂可以解决这个问题【参考方案2】:

限制对特定类的访问的唯一方法是使方法受保护或包私有。两者都只允许在包内访问。我建议重新格式化你的包结构。

【讨论】:

是的,你是对的。看来我读错了。我会修改帖子以反映这一点。【参考方案3】:

在方法内部,可以插入:

Throwable th = new Throwable().fillInStackTrace();
StackTraceElement element = th.getStackTrace()[TEST BETWEEN 3 AND 5];

if (element.getClassName().startsWith("your.package")) 
  // CONTINUE YOUR METHOD.

else 
  // USER ACCESSING FROM AN APPLICATION.
  // THROW EXCEPTIONS, SHUTDOWN THE SYSTEM... DO WHAT YOU WANT.

在第二行,在 3、4 和 5 之间进行测试,看看哪一个返回正确的element.getClassName()

【讨论】:

【参考方案4】:

您可以将项目拆分为 2:公共 API 及其实现。 为B类定义2个接口:

    图书馆用户的公共界面(在 API 项目中)。 您的内部接口扩展了公共接口并添加了方法 M。

用户将在编译时依赖于您的 API,并将在运行时获得实现。

【讨论】:

【参考方案5】:

你可以使用反射。这是一个例子。

package b;

public class B 
    private void m() 
        System.out.println("Called m()");
    

package a;

import b.B;

import java.lang.reflect.Method;

public class A 
    public static void main(String[] args) throws Exception 
        B b = new B();
        Method m = B.class.getDeclaredMethod("m");
        m.setAccessible(true);
        m.invoke(b);
    

哪些输出

调用 m()

【讨论】:

客户端不能也这样改修饰符吗?这太可怕了。 @TravelingSalesman 是的,根据您的代码运行的环境,可以使用反射访问任何私有方法

以上是关于我需要有一个可以从我的 API 中的任何位置访问但不能从使用 API 的应用程序访问的 java 方法的主要内容,如果未能解决你的问题,请参考以下文章

是否有任何 API 可以将跟踪号和订单状态从我的应用程序添加到 PayPal?

如何从我的应用程序访问 google drive api

是否有 API 可以访问移动设备上的位置历史记录?

从我的Mac查询到Pandas DataFrame的DB2 sql

如何从我的 Ruby on Rails API 解析这些散列转换为字符串,以便它可以作为 Javascript 中的对象进行访问?

chrome 中的 Angularjs 应用程序中的 CORS 错误访问 .NET Web Api