运行时类型解析的Java最佳实践

运行时类型解析的Java最佳实践,java,overloading,dynamic-typing,loose-typing,Java,Overloading,Dynamic Typing,Loose Typing,我试图定义一个类(或实现相同接口的一组类),该类将作为松散类型的对象(如JavaScript)。它们可以保存任何类型的数据,对它们的操作取决于基础类型 我有三种不同的方法,但似乎都不理想。这些测试版本只允许字符串和整数,唯一的操作是add。添加整数会得到整数值之和,添加字符串会连接字符串,向字符串添加整数会将整数转换为字符串并与字符串连接。最终版本将有更多类型(双精度、数组、类似JavaScript的对象,可以动态添加新属性)和更多操作 方式1: public interface DynObje

我试图定义一个类(或实现相同接口的一组类),该类将作为松散类型的对象(如JavaScript)。它们可以保存任何类型的数据,对它们的操作取决于基础类型

我有三种不同的方法,但似乎都不理想。这些测试版本只允许字符串和整数,唯一的操作是add。添加整数会得到整数值之和,添加字符串会连接字符串,向字符串添加整数会将整数转换为字符串并与字符串连接。最终版本将有更多类型(双精度、数组、类似JavaScript的对象,可以动态添加新属性)和更多操作

方式1:

public interface DynObject1 {
  @Override public String toString();
  public DynObject1 add(DynObject1 d);
  public DynObject1 addTo(DynInteger1 d);
  public DynObject1 addTo(DynString1 d);
}


public class DynInteger1 implements DynObject1 {
  private int value;

  public DynInteger1(int v) {
    value = v;
  }

  @Override
  public String toString() {
    return Integer.toString(value);
  }

  public DynObject1 add(DynObject1 d) {
    return d.addTo(this);
  }

  public DynObject1 addTo(DynInteger1 d) {
    return new DynInteger1(d.value + value);
  }

  public DynObject1 addTo(DynString1 d)
  {
    return new DynString1(d.toString()+Integer.toString(value));
  }
}
…与DynString1类似

方式2: 公共接口DynObject2{ @重写公共字符串toString(); 公共DynObject2 add(DynObject2 d); }

…与DynString2类似

方式3:

public class DynObject3 {

  private enum ObjectType {
    Integer,
    String
  };

  Object value;
  ObjectType type;

  public DynObject3(Integer v) {
    value = v;
    type = ObjectType.Integer;
  }

  public DynObject3(String v) {
    value = v;
    type = ObjectType.String;
  }

  @Override
  public String toString() {
    return value.toString();
  }

  public DynObject3 add(DynObject3 d)
  {
    if(type==ObjectType.Integer && d.type==ObjectType.Integer)
    {
      return new DynObject3(Integer.valueOf(((Integer)value).intValue()+((Integer)value).intValue()));
    }
    else
    {
      return new DynObject3(value.toString()+d.value.toString());
    }
  }
}
使用if-else逻辑,我可以使用value.getClass()==Integer.class,而不是存储类型,但如果使用更多类型,我会将其更改为使用switch语句,Java不允许switch使用类


无论如何。。。我的问题是,做这样的事情最好的方法是什么?

你想做的事叫做。您希望调用的方法既取决于调用它的对象的运行时类型,也取决于其参数的运行时类型


Java和其他C衍生工具只支持单一分派,这就是为什么您需要像选项1中使用的那样的混乱。这是实现它的常用方法。我更喜欢这种方法,因为它不使用反射。此外,它允许您将每个案例保留在自己的方法中,而不需要一个大的“交换机”方法来进行分派。

我选择第二个选项,第三个选项,我最好使用泛型,这样您就不必依赖于该枚举。有了第一种选择,你就可以在你的余生中实现各种方法。无论如何,您可以使用“instanceof”操作符进行类匹配。

顺便说一句,如果我的Java知识没有让我失望,
Class c=d.getClass();if(c==DynInteger2.class)
可以写成
if(DynInteger2的d实例)
public class DynObject3 {

  private enum ObjectType {
    Integer,
    String
  };

  Object value;
  ObjectType type;

  public DynObject3(Integer v) {
    value = v;
    type = ObjectType.Integer;
  }

  public DynObject3(String v) {
    value = v;
    type = ObjectType.String;
  }

  @Override
  public String toString() {
    return value.toString();
  }

  public DynObject3 add(DynObject3 d)
  {
    if(type==ObjectType.Integer && d.type==ObjectType.Integer)
    {
      return new DynObject3(Integer.valueOf(((Integer)value).intValue()+((Integer)value).intValue()));
    }
    else
    {
      return new DynObject3(value.toString()+d.value.toString());
    }
  }
}