gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-11-01 03:30:03 27 4
gpt4 key购买 nike

我正在尝试定义一个类(或一组实现相同接口(interface)的类),该类将表现为松散类型的对象(如 JavaScript)。根据底层类型,它们可以保存任何类型的数据和操作。

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

方式一:

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 类似

方式二: 公共(public)接口(interface) DynObject2 { @Override public String toString(); 公共(public) DynObject2 添加(DynObject2 d);

public class DynInteger2 implements DynObject2 {
private int value;

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

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

public DynObject2 add(DynObject2 d) {
Class c = d.getClass();

if(c==DynInteger2.class)
{
return new DynInteger2(value + ((DynInteger2)d).value);
}
else
{
return new DynString2(toString() + d.toString());
}
}
}

...和 ​​DynString2 类似

方式三:

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类(class)。

无论如何...我的问题是解决此类问题的最佳方法是什么?

最佳答案

你正在尝试做的是 double dispatch .您希望调用的方法既取决于调用它的对象的运行时类型,也取决于其参数的运行时类型。

Java 和其他 C 派生产品只支持单一分派(dispatch),这就是为什么你需要像 visitor pattern 这样的组合您在选项 1 中使用过。这是实现它的常用方法。我更喜欢这种方法,因为它不使用反射。此外,它允许您将每个案例保存在它自己的方法中,而不需要一个大的“交换机”方法来进行调度。

关于运行时类型解析的 Java 最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2786666/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com