Java 制作一个变量';s实例类型与另一个实例类型相同,根据接口编程

Java 制作一个变量';s实例类型与另一个实例类型相同,根据接口编程,java,reflection,Java,Reflection,我正在编写一些处理HTTP响应头的代码(一个填充后的不可变集合),发现自己的代码如下所示: private Map<String,String> headers; public ctor() { this.headers = new Hashtable<String,String>(); // ... some more ... (actually, this fills this.headers based on ctor parameters) }

我正在编写一些处理HTTP响应头的代码(一个填充后的不可变集合),发现自己的代码如下所示:

private Map<String,String> headers;

public ctor() {
    this.headers = new Hashtable<String,String>();
    // ... some more ... (actually, this fills this.headers based on ctor parameters)
}

public Map<String,String> getResponseHeaders() {
    Map<String,String> temp = new Hashtable<String,String>();
    temp.putAll(this.headers);
    return temp;
}
私有映射头;
公职人员(){
this.headers=新哈希表();
//…更多…(实际上,这会根据ctor参数填充this.headers)
}
公共地图getResponseHeaders(){
Map temp=新哈希表();
临时putAll(此标题);
返回温度;
}
看到这一点,我突然想到,虽然我现在知道了
标题的类型,而且无可否认,所讨论的类足够短(目前总共大约50行,并且不会增长太多),但在这种特殊情况下,这不是一个大问题,如果问题空间稍微复杂一点,那么在
getResponseHeaders()中
我可能不知道将
this.headers
(使用此特定示例中的名称)实例化为的类型。另外,在我想要返回集合副本的大型类中,跟踪许多不同的实例成员变量及其类型(可能由许多因素决定;列表大小是一个可能的考虑因素)可能会变得非常棘手

两个相关问题:

如果没有一个完整的依赖注入框架,并且禁止全面使用反射(因为性能损失),那么对于一般情况,有没有办法使
temp
的实例类型与上述代码中
this.headers
的实例类型相同


在任何情况下,这可能会产生很大的影响吗?

您可以调用
this.headers.clone()
,但需要强制转换结果。此外,这仅适用于类型为可克隆的情况,并且克隆完全符合您的要求(例如,在本例中为浅克隆)

除此之外,没有任何可能性,因为访问
this.headers的运行时类型(您称之为实例类型)已经涉及反射。然而,我不会因为有人说反射很慢就不使用反射。并不是所有的反射操作都很慢(例如,我希望调用对象上的
getClass()
会非常快),也不是所有执行的操作都会对应用程序的性能产生影响。这取决于更多的因素,例如,执行此操作的频率、优化器的性能等

反射的问题更多的是没有通用的方法来实例化特定的类型。如果类需要构造函数参数,则需要知道要传递给构造函数的对象

因此,考虑一下:您真的需要确保is是完全相同的运行时类型吗?通常情况并非如此。针对接口编程的全部要点是,您通常不应该关心真正的运行时类型,而应该只关心它实现了正确的接口(
Map
)。因此,当前形式的getter就可以了,即使
this.headers
的运行时类型将来实际上是一个
TreeMap

然而,在这个特定的情况下,我会建议一个完全不同的解决方案。我认为在每次调用
getResponseHeaders
时创建整个集合的副本是不好的(例如,我想这比反射方法调用要昂贵得多)。相反,您可以将集合的不可修改视图传递给调用者。使用此不可修改的视图,调用方将无法更改您的集合,这通常是您想要确保的。因此,通常不需要复制整个收藏

通过将getter方法更改为

return java.util.Collections.unmodifiableMap(this.headers);

请注意,通过这种方式,如果在调用
getResponseHeaders
后更改
this.headers
,调用方将看到映射的更改。

我建议使用Java集合框架中的类型(在本例中为
HashMap
,但也为
ArrayList
等),而不是以前的JCF类(
Hashtable
Vector
)。那里的API通常更干净,而且它们都很好地结合在一起。旧的类被改造成新的接口,这就是为什么它们的API不那么好(例如,重复的方法太多)。我想新类的实现也更好。即使只提到
unmodifiableMap()
我也会给出+1;我完全没有提到这一点,而且它几乎避免了整个问题,至少在我目前的情况下是这样。我也会考虑
HashMap