IntelliJ为Java类创建自定义警告
我也创建了一个IntelliJ为Java类创建自定义警告,java,intellij-idea,Java,Intellij Idea,我也创建了一个 是否可以为我的other类创建这样的自定义警告,以便在不首先选中other::isLeft()的情况下调用other::asLeft()将生成警告?假设IntelliJ(社区版)中有自定义警告功能,它是否允许这种复杂性?是的,通过开发插件,理论上这是可能的。然而,实际上,我建议不要这样做,因为实施这种检查可能需要很多努力。但是,您可以通过更改类并创建一个方法getLeftOrNull()来利用IntelliJ的null检查,该方法将被标记为@Nullable,并将返回null而不
是否可以为我的other
类创建这样的自定义警告,以便在不首先选中other::isLeft()
的情况下调用other::asLeft()
将生成警告?假设IntelliJ(社区版)中有自定义警告功能,它是否允许这种复杂性?是的,通过开发插件,理论上这是可能的。然而,实际上,我建议不要这样做,因为实施这种检查可能需要很多努力。但是,您可以通过更改类并创建一个方法getLeftOrNull()
来利用IntelliJ的null检查,该方法将被标记为@Nullable
,并将返回null而不是引发异常。然后IntelliJ会警告您,如果您在取消引用之前没有检查null
另一个选项是使用java 8 Optional并创建一个方法getLeftOptional()
,该方法将包装返回值,并在返回值为空时强制调用方处理大小写(即或为右)
/**
* 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());
}
}
Either<A,B> e = ....; //Take an either reference
if(e.isLeft()) {
A a = e.asLeft();
//Handle a
} else {
B b = e.asRight();
//Handle b
}