3 回答

TA貢獻1890條經驗 獲得超9個贊
這稱為聯合或變體類型(請參閱C++ 中的Boost.Variant)。后者特別方便,因為它是一組異構類型的類型安全容器,并且最接近您對要移植的代碼類型的描述。由于 Java 不支持模板——不,泛型不是模板——你不會得到你正在尋找的東西。
Optional類型是兩種類型中最簡單的情況:類型 T 和 Null 。鑒于您需要存儲的不僅僅是 T 或 Null 類型,它對您不起作用。
您可能想查看JavaSealedUnions。此外,Kotlin 提供了密封類的概念,有助于將值限制為受約束集中的一種類型。

TA貢獻1871條經驗 獲得超8個贊
這是我能想到的最好的。我認為你不能輕易地制作一個通用類型,而不是它是所有類的父類(如對象)??紤]到類型系統,轉換也很困難,您可以通過不允許重新分配不同類型的指針來模仿它,而每次執行獲取時只生成一個新指針。如果你不想知道類型本身,你可以在現代 java 中使用 var 來隱藏類型差異。
public class Types {
public static void main(String[] args) {
var p = new PascalPointer<>(new PascalInt());
PascalInt i = p.get();
var p2 = new PascalPointer<>(i.toPStr()); // mimic generics by type inference.
PascalString s = p2.get();
PascalPointer<PascalType> genericPointer = new PascalPointer<>(s);
genericPointer.set(i);
var i2 = (PascalInt) genericPointer.get();
}
public interface PascalType { }
public static class PascalInt implements PascalType {
// cast
public PascalString toPStr() {
return new PascalString(); // hide a new to do a conversion instead of a cast really.
}
}
public static class PascalString implements PascalType { }
public static class PascalPointer<T extends PascalType> {
T t;
public PascalPointer(T t) { this.t = t; }
public T get() { return t;}
public void set(T t) {this.t = t;}
}
}
當您想要一個字符串的 Int 視圖并更新字符串時,這可能會發生故障(正如我在這里復制的那樣)。

TA貢獻1770條經驗 獲得超3個贊
對于冗長的回答,我深表歉意。
我不認為你可以在不失去類型安全的情況下使用泛型實現你想要的。
為了使下一行工作,Java 需要知道Truck該方法返回了一個,defer()以便它可以調用honk()該對象。
p.deref().honk();
但是,如果您使用 Java 泛型,那么這會在編譯時推斷出類型擦除。
該解決方案意味著添加一個通用類型,例如Pointer<Truck>,但我們不能,因為您希望能夠添加十幾個特定的已知類型和一個Pointer.
但是......由于您自己編寫了這樣的行,特別是調用bark()orhonk(),
這意味著您已經知道Pointer引用 aDogorTruck對象。
使用該假設、泛型和對 的修改defer(),您可以非常接近解決方案。
假設我們有這些類,它們沒有任何鏈接。
public class Dog {
public void bark() {
System.out.println("Bark ...");
}
}
public class Truck {
public void honk() {
System.out.println("Honk ...");
}
}
然后我們需要一個像這樣的Pointer類,其中deref()方法需要一個Class參數來知道要返回哪個類型。
public class Pointer {
private Object myObj;
public <T> void ref(T myObject) {
this.myObj = myObject;
}
public <T> T deref(Class<T> myClazz) {
try {
return myClazz.cast(myObj);
} catch(ClassCastException e) {
return null;
}
}
}
然后您可以執行以下操作
public static void main(String[] args) {
Pointer pointer = new Pointer();
Dog dog = new Dog();
pointer.ref(dog); // Reference to a Dog
pointer.deref(Dog.class).bark();
Truck truck = new Truck();
pointer.ref(truck); // Reference to a Truck
pointer.deref(Truck.class).honk();
Pointer subPointer = new Pointer();
pointer.ref(subPointer); // Reference to another pointer
subPointer.ref(truck); // Other pointer references a Truck
pointer.deref(Pointer.class).deref(Truck.class).honk();
subPointer.ref(dog); // Other pointer references a Dog
pointer.deref(Pointer.class).deref(Dog.class).bark();
pointer.ref(null); // Clears the reference
Truck bulldog = new Truck();
pointer.ref(bulldog);
pointer.deref(Dog.class).bark(); // Is allowed, but will cause a NullPointerException
}
這將打印出:
Bark ...
Honk ...
Honk ...
Bark ...
在 Pointer.main(Pointer.java:39) 的線程“主”java.lang.NullPointerException 中出現異常
如果您需要將Pointer引用限制為僅對您的十幾個特定已知類型和Pointer類本身,那么您需要使用超類(例如Pointerable)擴展它們并相應地修改ref()方法。
然后,您可以防止不擴展此超類的類型被您的指針引用。
例子:
public abstract class Pointerable { }
public class Dog extends Pointerable {
public void bark() {
System.out.println("Bark ...");
}
}
public class Pointer extends Pointerable {
private Object myObj;
public <T extends Pointerable> void ref(T myObject) {
this.myObj = myObject;
}
public <T extends Pointerable> T deref(Class<T> myClazz) {
try {
return myClazz.cast(myObj);
} catch(ClassCastException e) {
return null;
}
}
添加回答
舉報