简体   繁体   English

Java最佳实践:将/获取SubClass对象放入需要SuperClass对象的HashMap中

[英]Java best practices: Put/Get SubClass objects into HashMap that expects SuperClass objects

Let's say I instantiate a HashMap with SuperClass as value-type. 假设我使用SuperClass将HashMap实例化为值类型。 I then add SubClass objects as values to the Map. 然后我将SubClass对象作为值添加到Map。 When I retrieve those values from the Map, they are returned as objects of type SuperClass , which I explicitly cast back to Subclass : 当我从Map中检索这些值时,它们将作为SuperClass类型的对象返回,我明确地将其转换回Subclass

class SuperClass {}

class SubClass1 extends SuperClass { int one;}

class SubClass2 extends SuperClass { int two;}

class DoSomething {

   DoSomething() {
      Map<String, SuperClass> map = new HashMap<String, SuperClass>();

      map.put("1", new SubClass1());
      map.put("2", new SubClass2());

      SubClass1 one = (SubClass1) map.get("1");
   }
}

I need to know that the returned object is of the specific SubClass because I want to access methods that only exist in the SubClass. 我需要知道返回的对象是特定的SubClass因为我想访问仅存在于SubClass中的方法。 If the returned type can be any number of different SubClasses, is the use of instanceof considered best practice in determining the type and the casting? 如果返回的类型可以是任意数量的不同SubClasses,那么在确定类型和转换时是否使用instanceof最佳实践?

SuperClass s = map.get("1");
if (s instanceof SubClass1) {
  (SubClass1)s.one = 1;
}

Thanks 谢谢

There are a number of ways about this depending upon the particular situation: 根据具体情况,有很多方法可以解决这个问题:

  • Add an abstract method to the superclass for performing the relevant operation. 向超类添加抽象方法以执行相关操作。
  • Use an adapter as the type of the map values. 使用适配器作为映射值的类型。 When adding the entries, use a specialisation of the adapter to match the subtype. 添加条目时,使用适配器的特化来匹配子类型。
  • Separate maps. 单独的地图。 Particularly good if they shouldn't have been in the same map in the first place. 如果他们不应该首先在同一张地图上,那就特别好。

The best practice should be putting each SubClass type inside a different Map. 最佳实践应该是将每个SubClass类型放在不同的Map中。

Using instanceof before performing a cast, if you really need to do that cast, it's a good idea because this way you will prevent a ClassCastException. 在执行转换之前使用instanceof,如果你真的需要进行转换,那么这是一个好主意,因为这样你就可以防止出现ClassCastException。

Pay attention that if your code has a lot of instanceof directives then you could have a bad design. 请注意,如果您的代码有很多instanceof指令,那么您可能会有一个糟糕的设计。

If you want to put them in the same Map then you need to think about your design: 如果你想把它们放在同一个Map中,你需要考虑你的设计:

have your DoSomething class to be aware of the differents SubClass types to perform specific operation?I see 3 possibilities: 让你的DoSomething类知道不同的SubClass类型来执行特定的操作吗?我看到3种可能性:

  1. Yes, DoSomething must be aware of all your SubClass types. 是的,DoSomething必须知道所有的SubClass类型。 Then don't worry, perform your check with instanceof and cast the object retrieved from the map or, better, store them into different Maps. 然后不要担心,使用instanceof执行检查并转换从地图检索到的对象,或者更好地将它们存储到不同的地图中。
  2. No, DoSomething doesn't need to be aware of the different SubClass because can use them throw the common interface SuperClass . 不,DoSomething不需要知道不同的SubClass因为可以使用它们抛出公共接口SuperClass。 That's good design. 这是个好设计。
  3. You don't want DoSomething to be aware of different SubClass types, but in certain situation you feel the needs to use some subclass specific methods: refactor your code, you have a wrong design. 你不希望DoSomething知道不同的SubClass类型,但在某些情况下你觉得需要使用一些子类特定的方法:重构你的代码,你的设计是错误的。

Yes, you should definitely use instanceof to be typesafe. 是的,你绝对应该使用instanceof来进行类型安全。 Otherwise, how would you know whether or not the object you pulled out is in fact the correct subclass? 否则,你怎么知道你拔出的对象实际上是否是正确的子类?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM