与大多数Singleton类一样,是否存在使用私有构造函数“扩展”类的标准技术?具体来说,我正在尝试扩展java.lang.management.ThreadInfo
类,因为我将很多它们添加到HashSet
来控制唯一性。但是,我确定两个线程是否相等的方式是不同的,并且与equals()
方法的默认实现不同。
在这种情况下,扩展课程显然不是一种选择。
在构造函数中创建类似于包含ThreadInfo
的包装类,然后使用值手动填充所有相关字段,然后覆盖equals()
和hashCode()
,是否合理?或者有更好的方法吗?
这样的事情就是我开始写的,但更好的实现是理想的:
class ThreadInfoWrapper {
private ThreadInfo info;
ThreadInfoWrapper(ThreadInfo info) {
this.info = info;
}
//Populate instance variables with Thread.State, thread ID, etc.. with
//Getters/setters and all that other stuff
public boolean equals(Object o) { //Unique implementation
}
public int hashCode() { //Whatever implementation
}
}
但这感觉就像是一种非常迂回的方式来实现一些基本功能。我调查了一下,Java标准库中不存在使用自定义比较器的集合的实现。我想我可以编写自己的哈希集实现,但这对于一个简单的情况来说太过分了。任何见解都会有所帮助。
答案 0 :(得分:2)
通过扩展,您的意思是如何创建派生类,它们使用私有构造函数作为其超类构造函数。你不能,他们是私人的,以防止你这样做。由于JRE课程是由有能力的程序员编写的,因此有充分的理由。因此,即使您可以使用欺骗(例如反射或字节码操作)来解决它,也不应该这样做。
但并非一切都没有丢失。无论如何,你应该更喜欢组合继承。装饰器和代理设计模式可能很有用(您的示例接近这些)。
答案 1 :(得分:1)
我认为你所做的事情是合理的,因为其他选择很少。
另一种方法是编写自己的HashMap子类,使用“特殊”等于而不是默认值。 (可能已经有apache或guava实现了 - 任何人都知道了吗?)
(稍后补充)
因为我很懒,并且因为ThreadInfo有所有getter所以它暴露相当“安全”,所以我很想让包装类非常简单,没有getter或setter:
public class ThreadInfoWrapper {
// public so an outsider can get at the wrapped ThreadInfo
// could be private if you are sure that will never be necessary
public final ThreadInfo threadInfo;
public ThreadInfoWrapper(ThreadInfo threadInfo) {
this.threadInfo = threadInfo;
}
public boolean equals(Object o) { //Unique implementation
// refer to threadInfo.blah...
}
public int hashCode() { //Whatever implementation
// refer to threadInfo.blah...
}
}
但是,这取决于您为equals和hashcode使用的信息。