Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检查对象是否为受保护类的实例_Java_Protected_Instanceof_Jooq - Fatal编程技术网

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

Java 检查对象是否为受保护类的实例,java,protected,instanceof,jooq,Java,Protected,Instanceof,Jooq,假设我使用的Java库具有以下方法 public static SomeInterface foo(); 接口SomeInterface有多个实现,其中一些在库的包中受到保护。其中一个实现是ProtectedClass 检查foo()返回的对象是否是受保护类的实例的最佳方法是什么 我当前的计划是创建一个Utils类,该类位于我的项目中,但与受保护类位于同一个包中。此实用程序可以引用受保护的类,因为它位于同一个包中,因此它可以检查对象是否是受保护类的实例 还有其他想法吗 编辑:有些人问“为什么”

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

public static SomeInterface foo();
接口
SomeInterface
有多个实现,其中一些在库的包中受到
保护。其中一个实现是
ProtectedClass

检查
foo()
返回的对象是否是受保护类
的实例的最佳方法是什么

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

还有其他想法吗

编辑:有些人问“为什么”,所以这里有更多的上下文

我正在使用,在代码的某些部分,我想知道我拥有的实例是否是的实例

目前,我使用的是
field.getName().equals(“lower”)
,但这并不像我希望的那样健壮

我意识到,由于
Lower
是一个受保护的类,它不是API的一部分,它可以更改,但我同意这一点

Class.forName("TheProtectedClass").isAssignableFrom(foo())
虽然这是一个坏主意,原因很多。你打破了这里的封装和抽象。如果是私人包裹,你不应该在外面担心。如果它受到保护,您应该显式地从它继承,并使用类为这种情况提供的API

不太明显但更正确的解决方案是获取受保护类的实例,并通过

guaranteedTPCInstance.getClass().isAssignableFrom(foo())
,虽然仍然有点黑客味,但至少在我看来,它更便携、更酷

至于您在与ProtectedClass相同的包中创建一个类以避免包私有的想法,这是一个可行的解决方案,但a)它破坏了封装的基本原则和TPC类的编程契约;由库/类作者进行打包是有原因的-为了防止不负责任的数据访问和使用私有API或未记录的专有方法,b)这并不总是可能的(并且在正确设计库类的情况下不应该是可能的),因为这些类不仅可以是包私有的,但是
final
或者有效的final(匿名内部类等)-由于Bloch在EJ 2nd中描述的原因,“支持组合而不是继承”项,请参见etc c)您不能使用一些Java库类,因为您不能定义您的类并使用例如
Java.lang
包。因此,唯一的“可移植”解决方案是通过反射和我描述的内容

tl;dr通过模仿另一个包的定义,您可以搭载另一个包,这是Java语法的一个明显的C风格缺陷(允许程序员做他通常不能做的事情;某些特定的反射方法也是如此);这样做的黑客既不可维护也不安全


注意:如果您希望以依赖于内部实现的方式执行某些操作,同时以可移植和可维护的方式(例如,不受实现更改/类名更改的影响等)执行这些操作,显然,您在期待不可能的结果。

看来,最好的解决方案是在项目中创建一个与包私有类具有相同包的包,并将受保护的class.class
公开为一个
,或者简单地添加一个检查
对象
是否为
实例的简单方法受保护的类


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

您可以通过反射来完成,但为什么要这样做?多个实现,其中一些实现受到保护您的意思是什么。类具有
公共
默认
可见性。当然,最好的方法是首先避免执行
实例的
检查?当其任何超类或超接口受
保护
私有
时,实例是否受保护,或者包私有?了解用例背后的基本原理会很有趣。也许你真正想做的事情可以通过使用jOOQ API以其他方式实现?我发现这个解决方案不如我在帖子中提出的UTIL解决方案,因为如果
ProtectedClass
在库版本之间更改名称,它将不会破坏编译。1)你询问了其他想法-目前还没有其他方法可以做到这一点,因此,它不如您提出的解决方案(可以说)这一事实只突出表明,您试图实现的目标本身就是黑客行为,2)请参阅下面的我的编辑,以获得更可移植的版本,不依赖于TPC类名,3)如果您不想从其名称或其实例对象推断受保护的类,您希望如何显示应用程序“我正在谈论这个特定的类”?“Lukasead A”,您是否考虑过这样一个事实,即允许在非显式文档化的继承案例中继承是一个反模式?更不用说继承本身通常是一种反模式,因为大多数人就是做不好,正如OP problem所示——这正是Bloch所说的(不仅仅是他,因为“更喜欢组合而不是继承”是一种常见的良好编程实践,而不是合成规则,请参见)CDS进行了深入的讨论。这就是为什么Bloch和其他许多人(包括我)说“如果它不是明确设计为扩展的,则将其作为最终版本以防止继承。如果它是明确设计为扩展的,则对其进行文档记录并使API直接,以便可以在不引入错误和混乱的情况下进行继承”;在这种情况下,由于OPs需求与jOOQ的API提供的函数相比,解决方案是一个混乱的问题,它证明了类不应该允许继承到外部代码。我不会离题讨论做这件事的方法和为什么要做(有很多关于这件事的好书),事实是