英文:
Casting between class objects in java
问题
我有两个类Float2
和Double2
public final class Float2 {
public float width;
public float height;
public Float2 multiplyBy(float number) {
return new Float2(this.width * number, this.height * number);
}
}
public class Double2 {
public double width;
public double height;
}
我想将multiplyBy
方法的结果转换为Double2
,这样最终我就不会有Float2 newRectangleSize = rectangleSize.multiplyBy(3.2f);
,而是Double2 newRectangleSize
作为乘法的结果。当然,我可以分别转换宽度和高度的值,但我想知道在Java中是否有更优雅的解决方案?
英文:
I have two classes Float2
&& Double2
public final class Float2 {
public float width;
public float height;
public Float2 multiplyBy(float number) {
return new Float2(this.width * number, this.height * number);
}
}
public class Double2 {
public double width;
public double height;
}
I want to cast the result of multiplyBy method to a Double2 so that in the end I do not have Float2 newRectangleSize = rectangleSize.multiplyBy(3.2f);
but Double2 newRectangleSize
as the result of multiplication. Of course I can cast width and height values separately but I was wondering if there was a more ellegant solution in java?
答案1
得分: 1
清楚地看出,在这种情况下进行强制类型转换将会导致 ClassCastException
。一个选项是支持一个接口,该接口由这两个类实现,允许将 width()
和 height()
定义为 Number 对象,甚至是扩展 Number 的类型。然后,你可以根据实现的情况来处理转换,以处理像 int 或 short 这样的情况下的精度损失。
interface Size<T extends Number> {
T width();
T height();
}
另一个选项可能是为这些类提供静态工厂方法,以允许在 Double2 和 Float2 之间进行转换。可能会像这样:
public class Double2 {
private final double width;
private final double height;
public Double2(double width, double height) {
this.width = width;
this.height = height;
}
public static Double2 valueOf(Float2 float) {
return new Double2((double) float.width, (double) float.height);
}
}
Float2 float2 = new Float2(2f, 2f).multiplyBy(2f);
Double2 double2 = Double2.valueOf(float2);
英文:
So clearly trying to cast in this case will result in a ClassCastException
. One option would be to support an interface that is implemented by both classes that allows width() and height() to be defined as Number objects or even a type that extends Number. Then you could handle conversion on a implementation by implementation basis to handle precision loss in cases like int or short.
interface Size<T extends Number> {
T width();
T height();
}
Another option might be to provide static factory methods to these classes to allow for the conversion of Double2 to Float2 and vice versa. It might look like this;
public class Double2 {
private final double width;
private final double height;
public Double2(double width, double height) {
this.width = width;
this.height = height;
}
public static Double2 valueOf(Float2 float) {
return new Double2((double) float.width, (double) float.height);
}
}
Float2 float2 = new Float2(2f, 2f).multiplyBy(2f);
Double2 double2 = Double2.valueOf(float2);
答案2
得分: 1
如果Double2
和Float2
是相关的类型,那么可能可以进行类型转换。
只要它们不是相关的,无论参数的名称和类型是否相同,都无法进行类型转换。然而,您可以利用基于反射的框架的优势,使类型之间的映射变得容易,例如MapStruct:
@Mapper
public interface Double2Mapper {
Double2Mapper INSTANCE = Mappers.getMapper(Double2Mapper.class);
@Mapping
Double2 floatToDouble(Float2 float2);
}
Double2 double2 = Double2Mapper.INSTANCE.floatToDouble(rectangleSize.multiplyBy(3.2f));
如果您不想使用框架(只适用于少数特定和简单的情况),我为您提供了两种基于纯面向对象编程的基本方法:
-
使用
Float2
的构造函数创建Double2
(假设字段保持为public
):public Double2(Float2 float2) { this.width = float2.width; this.height = float2.height; }
-
在
Float2
类中创建一个返回此类型的方法:public Double2 asDouble2() { return new Double2(this.width, this.height); }
英文:
If Double2
and Float2
would be related types then casting could be possible.
As long as they aren't, you cannot cast them regardless the names of parameters are same including their types. However, you can use this advantage for a framework based on reflection that makes mapping between types easy, such as MapStruct:
@Mapper
public interface Double2Mapper {
Double2Mapper INSTANCE = Mappers.getMapper(Double2Mapper.class);
@Mapping
Double2 floatToDouble(Float2 float2);
}
Double2 double2 = Double2Mapper.INSTANCE.floatToDouble(rectangleSize.multiplyBy(3.2f));
If you are not keen to use a framework (in case of only few specific and simple cases), I offer you two basic ways based on the pure OOP:
-
A constructor of
Double2
usingFloat2
(assuming the fields remainpublic
):public Double2(Float2 float2) { this.width = float2.width; this.height = float2.height; }
-
A method returning such type in the class
Float2
:public Double2 asDouble2() { return new Double2(this.width, this.height); }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论