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