在Java中的类对象之间进行类型转换

huangapple go评论87阅读模式
英文:

Casting between class objects in java

问题

我有两个类Float2Double2

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&lt;T extends Number&gt; {

    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

如果Double2Float2是相关的类型,那么可能可以进行类型转换。

只要它们不是相关的,无论参数的名称和类型是否相同,都无法进行类型转换。然而,您可以利用基于反射的框架的优势,使类型之间的映射变得容易,例如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));

如果您不想使用框架(只适用于少数特定和简单的情况),我为您提供了两种基于纯面向对象编程的基本方法:

  1. 使用Float2的构造函数创建Double2(假设字段保持为public):

    public Double2(Float2 float2) {
        this.width = float2.width;
        this.height = float2.height;
    }
    
  2. 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:

  1. A constructor of Double2 using Float2 (assuming the fields remain public):

    public Double2(Float2 float2) {
        this.width = float2.width;
        this.height = float2.height;
    }
    
  2. A method returning such type in the class Float2:

    public Double2 asDouble2() {
        return new Double2(this.width, this.height);
    }
    

huangapple
  • 本文由 发表于 2020年8月28日 01:28:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/63621308.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定