我創建了Either<A,B>
類來表示總和類型。每個實例包裝A
或B
。這由擴展Left<A>
和Right<B>
表示。這些類型對用戶是隱藏的,僅用於存儲對A
或B
的引用,並在Either
中實現抽象方法。下面的代碼的相關部分:IntelliJ爲Java類創建自定義警告
/**
* A simple SumType implementation. Allows the creation of the Sum Type
* A + B. Every instance of Either is either (haha.. tomatoes, rocks)
* an instance of Left, with a value of type A, or an instance of Right,
* with a value of type B.
* <br><br>
* The types and constructors for Left and Right are not exposed.
* Instead, to construct new instance of Left and Right, the createLeft and createRight
* methods of class Either should be used.
* <br><br>
* The types can be the same, but in that case there isn't much use to using Either.
*
* @param <A> The first type to sum
* @param <B> The second type to sum
* @author Mshnik
*/
public abstract class Either<A, B> {
private final boolean isLeft;
/**
* Constructs a new Either
*
* @param isLeft - true if this is a Left, false if this is a Right
*/
Either(boolean isLeft) {
this.isLeft = isLeft;
}
/** Creates a Either instance of the given A */
public static <A, B> Either<A, B> createLeft(A a) {
return new Left<>(a);
}
/** Creates a Either instance of the given B */
public static <A, B> Either<A, B> createRight(B b) {
return new Right<>(b);
}
/**
* Returns true if this is a Left, false if this is a Right
*/
public boolean isLeft() {
return isLeft;
}
/**
* Returns the value of this Either as an an instance of A.
* If the wrapped value is an instance of B, throws a RuntimeException
*/
public A asLeft() {
if (isLeft())
return ((Left<A,B>)this).getVal();
throw new RuntimeException();
}
/**
* Returns the value of this Either as an an instance of B.
* If the wrapped value is an instance of A, throws a RuntimeException
*/
public B asRight() {
if (!isLeft())
return ((Right<A,B>)this).getVal();
throw new RuntimeException();
}
/**
* Returns the Object stored within this Either.
* Should have a stricter type bound (A or B) when implemented by subclasses.
*/
public abstract Object getVal();
/**
* Returns the type of the Object stored within this Either
*/
public abstract Class<?> getType();
/**
* Two Eithers are equal iff:
* <br>- They are both Left or both Right, the only two direct subclasses
* <br>- The objects they store are equivalent using Objects.equals.
*/
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null) return false;
try {
@SuppressWarnings("unchecked")
Either<A, B> e = (Either<A, B>) o;
return (!(isLeft^e.isLeft)) && Objects.equals(getVal(), e.getVal());
} catch (ClassCastException e) {
return false;
}
}
/**
* Hashes an either based on the value it stores.
* This maintains the hash invariant (two equal objects have the same hashcode),
* but is not a perfect hashcode because a Left(a) and Right(a) will have the
* same hashcode but are not equivalent.
*/
@Override
public int hashCode() {
return Objects.hashCode(getVal());
}
}
打算利用asLeft()
和asRight()
簡單,看起來像這樣:
Either<A,B> e = ....; //Take an either reference
if(e.isLeft()) {
A a = e.asLeft();
//Handle a
} else {
B b = e.asRight();
//Handle b
}
而且一直是非常有用的在我的項目的其餘部分。
現在我的問題 - 我主要使用IntelliJ(並喜歡它),並且已經注意到它有一個功能,可以阻止你做可能是錯誤的事情,比如將字符串與==
進行比較。
是否有可能創建這樣一個自定義警告我Either
類,這樣調用Either::asLeft()
沒有檢查Either::isLeft()
會生成一個警告?假設IntelliJ(社區版)具有自定義警告功能,它是否允許這種複雜性?