假设我正在使用具有以下方法的Java库
public static SomeInterface foo();
接口SomeInterface
有多个实现,其中一些是库中的protected
包。其中一个实现是TheProtectedClass
检查foo()
返回的对象是TheProtectedClass
的实例的最佳方法是什么?
我目前的计划是创建一个Utils类,它位于我的项目中但与受保护类位于同一个包中。此Utils可以引用TheProtectedClass
,因为它位于同一个包中,因此可以检查对象是否为instanceof TheProtectedClass
。
还有其他想法吗?
编辑:有些人在问"为什么"所以这里有更多的背景。我正在使用jOOQ,在我的部分代码中,我想知道我所拥有的Field实例是Lower的实例。
目前,我使用的是field.getName().equals("lower")
,但这并不像我希望的那样强大。
我意识到,由于Lower
是一个受保护的类,它不是API的一部分,它可以改变,但我对此感到满意。
答案 0 :(得分:2)
Class.forName("TheProtectedClass").isAssignableFrom(foo())
虽然出于很多原因这是一个坏主意。你在打破封装和抽象。如果它是包私有的,你不应该在外面关注它。如果它受到保护,您应该明确地继承它并使用类提供的API来处理这种情况。
不太明显但更正确的解决方案是获取TheProtectedClass
的实例,并通过
guaranteedTPCInstance.getClass().isAssignableFrom(foo())
,虽然仍然是一种hacky,至少是更便携和OOPy IMO。
关于在与TheProtectedClass相同的包中创建类以避免包私有的想法 - 这是一个可行的解决方案,但是a)它打破了封装的基本原则和TPC类的编程契约;包装是由库/类作者完成的,原因是为了防止不负责任的数据访问和使用私有API或未记录的专有方法,b)并不总是可行(并且在正确的情况下不应该设计的库类),因为这些类不仅可以是包私有,而且可以是final
或有效的最终(匿名内部类等) - 由于Bloch在EJ 2nd中描述的原因,“赞成组合而不是继承”项,另请参阅Good reasons to prohibit inheritance in Java? Use of final class in Java等c)您无法使用某些Java库类,因为您无法定义您的类并使用例如java.lang
包。因此,唯一的“便携式”解决方案是通过反思和我所描述的。
tl; dr你可以通过模仿它的包定义来搭载另一个包这一事实是一种明显的C风格的Java语法缺陷(允许程序员做他应该不能正常做的事情;同样适用于一些具体的反思方法);以这种方式制作的黑客既不可维护也不安全。
注意:如果您希望在内部实现依赖中执行某些操作,同时可移植和可维护(例如,不受实施变更/班级名称变更等影响的方式,你显然期待不可能。
答案 1 :(得分:0)
似乎最好的解决方案是在项目中创建一个包,该包与package-private类具有相同的包,并将TheProtectedClass.class
公开为Class<?>
或者只是添加一个简单的方法检查您的Object
是否为instanceof TheProtectedClass
。
这不需要反射,它快速且相对安全(如果包私有类更改名称,编译将中断)。