检查对象是否是受保护类的实例

时间:2014-08-20 14:23:48

标签: java protected instanceof jooq

假设我正在使用具有以下方法的Java库

public static SomeInterface foo();

接口SomeInterface有多个实现,其中一些是库中的protected包。其中一个实现是TheProtectedClass

检查foo()返回的对象是TheProtectedClass的实例的最佳方法是什么?

我目前的计划是创建一个Utils类,它位于我的项目中但与受保护类位于同一个包中。此Utils可以引用TheProtectedClass,因为它位于同一个包中,因此可以检查对象是否为instanceof TheProtectedClass

还有其他想法吗?

编辑:有些人在问"为什么"所以这里有更多的背景。

我正在使用jOOQ,在我的部分代码中,我想知道我所拥有的Field实例是Lower的实例。

目前,我使用的是field.getName().equals("lower"),但这并不像我希望的那样强大。

我意识到,由于Lower是一个受保护的类,它不是API的一部分,它可以改变,但我对此感到满意。

2 个答案:

答案 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

这不需要反射,它快速且相对安全(如果包私有类更改名称,编译将中断)。