Java中的自动类型转换?

时间:2010-03-09 01:57:29

标签: java type-conversion overloading

有没有办法在Java中进行自动隐式类型转换?例如,假设我有两种类型,'FooSet'和'BarSet',它们都是Set的表示。在类型之间转换很容易,因此我编写了两种实用方法:

/** Given a BarSet, returns a FooSet */
public FooSet barTOfoo(BarSet input) { /* ... */ }

/** Given a FooSet, returns a BarSet */
public BarSet fooTObar(FooSet input) { /* ... */ }

现在说我想要这样的方法:

public void doSomething(FooSet data) {
    /* .. */
}

但我拥有的只是BarSet myBarSet ...这意味着额外输入,例如:

doSomething(barTOfoo(myBarSet));

有没有办法告诉编译器某些类型可以自动转换为其他类型?我知道这可以在C ++中进行重载,但我找不到Java的方法。我想能够输入:

doSomething(myBarSet);

编译器知道自动调用barTOfoo()

6 个答案:

答案 0 :(得分:5)

答案很简单:在C ++中可能会出现重载,但在Java中无法做到这一点。

答案 1 :(得分:2)

你可能会重载你的方法,如下所示:

public void doSomething(FooSet data) {
    /* .. */
}

public void doSomething(BarSet data) {
    doSomething(barTOfoo(data));
}

答案 2 :(得分:1)

你们可以一起做两件事:

(1)编写在后台进行转换的包装方法。

(2)如果您的对象具有正确的hashCode覆盖方法,则包装器方法可以管理一个非常简单和快速的缓存,您可以使用简单的Map实现自己构建并可能同步(如果您完全同时使用对象。)

这将使你摆脱两种类型之间的转换,可能是性能问题。即使你反对缓存,我仍然会建议(如其他海报所说)使用包装方法。这至少可以为你节省大量不必要的打字。

祝你好运。

答案 3 :(得分:0)

重载以相反的方式工作,您在接收器对象上声明了两个方法:

public void doSomething(FooSet data)
{
    /* .. */
}

public void doSomething(BarSet data)
{
    doSomething(barToFoo(data));
}

然后感谢动态绑定wikipedia),在运行时选择正确的方法。

当然,Java中的重载的作用域是对象级的(因为调用仅限于实例或类声明),但它的工作方式相同。

在你的情况下你可以尝试扩展类,如果它在外部库中,因为它是java你应该能够做到,并添加方法或使用 reflection ({{ 3}})动态添加方法。

答案 4 :(得分:0)

不支持自动类型转换(您需要Scala的implicit type conversions)。

但您可以尝试使用Variant类型作为交换盒来切换类型:

/** Given a BarSet, returns a FooSet */
public Function<BarSet, FooSet> barTofoo = new Function<BarSet, FooSet>() {
    @Override public FooSet apply(BarSet input) { /* ... */ }
}

/** Given a FooSet, returns a BarSet */
public Function<FooSet, BarSet> fooToBar = new Function<FooSet, BarSet>() {
    @Override public BarSet apply(FooSet input) { /* ... */ }
}

/** Create a type conversion context in which both of these conversions are registered */
TypeConversionContext fooBarConversionContext = MatchingTypeConversionContext.builder()
    .register(FooSet.class, BarSet.class, fooToBar)
    .register(BarSet.class, FooSet.class, barToFoo)
    .build();

/** Put a FooSet into a Variant, bound to our type conversion context */
FooSet fooSet = new FooSet();
Variant data = Variant.of(fooSet).in(fooBarConversionContext);

/** Pull a BarSet out of the Variant */
public void doSomething(Variant data) {
    Preconditions.checkArgument(data.isConvertibleTo(BarSet.class);
    BarSet barSet = data.as(BarSet.class);
    // ...
}

答案 5 :(得分:-1)

创建Java时考虑了可见性。每个程序员都应该只读一行并了解那里发生的事情。这就是它没有运算符重载的原因,这就是为什么它没有任何类型的自动自定义类型转换。所以,除非你在一个库中编写自己的包装器,它将接受来自其他库的类型并明确地转换它们,否则你就不幸了。