亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何實例化泛型類型?

如何實例化泛型類型?

交互式愛情 2023-06-08 20:55:06
我正在為 Java 項目制作一些數學課程。我有一個 Vector3 類,但我還需要 Vector4 和 Vector2,但顯然我不想復制粘貼我的代碼 3 次。所以我所做的是一個 Vector 類,它將成為所有向量的母類。我可以只使用沒有子類的 Vector 類,但我更喜歡使用這些子類,因為我可以在它們上面添加特定的東西,比如 Vector3 中的歐拉角操作,而且我想使用 Vector4 作為四元數的母類。無論如何,這是我簡化的 Vector 類:public class Vector {    public double[] values;    public Vector(double[] values) {        this.values = values;    }    public int getLength() {         return values.length;     }    public static <T extends Vector> T multiply(T vector, double k) {        double[] values = new double[vector.getLength()];        for(int i = 0; i < values.length; i++)            values[i] = k* vector.values[i];        return new T(values);    }}public class Vector3 extends Vector {    public Vector3(double[] values) {        super(values);    }}問題是編譯器不會讓我實例化一個 T:“類型參數 T 不能直接實例化”。但是我需要這個 T 因為我需要返回的向量與發送的向量類型相同。如果我執行 new Vector2(4,2).multiply(42),我需要得到一個 Vector2 而不是一個 Vector。我還可以在 Vector2 中創建一個乘法方法,該方法調用 Vector multiply,然后將值復制到 Vector2 中,但是 1. 這很糟糕,2. 這意味著子向量之間有很多復制粘貼,3. 我需要性能,所以那不理想。我知道我可以使用反射來解決問題,但這些方法對性能至關重要,所以我必須盡可能簡單。我還考慮過更改參數中的向量,這樣我就不必實例化一個新的向量,但這是一個非常糟糕的主意,因為它會導致奇怪的行為。任何幫助表示贊賞。
查看完整描述

2 回答

?
當年話下

TA貢獻1890條經驗 獲得超9個贊

最簡單的方法似乎是在Vector類上有一個實例方法:


Vector make(double[] values) {

  return new Vector(values);

}

然后在每個子類中覆蓋它,使用協變返回類型:


class Vector3 extends Vector {

  //...


  @Override Vector3 make(double[] values) {

    return new Vector3(values);

  }


  //...

}

然后你可以在你的 multiply 方法中調用它。


return vector.make(values);

但老實說,我不會嘗試將向量的長度編碼為類型。當你需要一個包含 57032 個元素的向量時會發生什么?您肯定不想為此創建一個特定的類,對嗎?如果您有兩個Vector具有相同數量元素的不同子類,會發生什么情況:它們是否兼容(例如相加)?


更自然地處理向量的語言(例如 MATLAB)不會將其構建到類型中;問問自己是否真的需要這里。


查看完整回答
反對 回復 2023-06-08
?
LEATH

TA貢獻1936條經驗 獲得超7個贊

如果它對性能至關重要,您實際上可能會考慮讓 multiply 方法改變向量的狀態,而不是創建一個新的。在我看來,這并不奇怪,只要它是確定性的和記錄在案的行為即可。

但是,對于不可變向量類,您需要clone向量。

public class Vector implements Cloneable {

? ? // not a good idea to make it public, if you don't want any changes here

? ? private double[] values;


? ? public static <T extends Vector> T multiply(T vector, double k) {

? ? ? ? Vector temp = vector.clone();

? ? ? ? for(int i = 0; i < temp.values.length; i++)

? ? ? ? ? ? temp.values[i] = k * temp.values[i];

? ? ? ? // the clone method guarantees that 'temp' is of type T,

? ? ? ? // but since it is not generic, the compiler cannot check it

? ? ? ? @SuppressWarnings("unchecked")?

? ? ? ? T result = (T)temp;

? ? ? ? return result;

? ? }


? ? protected Vector clone() {

? ? ? ? try {

? ? ? ? ? ? Vector vector = (Vector)super.clone();

? ? ? ? ? ? vector.values = Arrays.copyOf(values, values.length);

? ? ? ? ? ? return vector;

? ? ? ? } catch (final CloneNotSupportedException exc) {

? ? ? ? ? ? // this is a weird design choice of `Object.clone()`, too,

? ? ? ? ? ? // but back then, we did not have annotations or anything equivalent

? ? ? ? ? ? throw new AssertionError("we forgot to implement java.lang.Cloneable", exc);

? ? ? ? }

? ? }

}


查看完整回答
反對 回復 2023-06-08
  • 2 回答
  • 0 關注
  • 201 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號