patternjavaMinor
Implementing equals(), hashCode(), toString() in the hierarchy like the Optional<?> from Guava
Viewed 0 times
thehierarchyhashcodelikeoptionalguavaequalsfromimplementingtostring
Problem
I have simple hierarchy which looks [a little bit] like the
```
public abstract class Result {
public static Result get(ResultType result) {
return new PresentResult(result);
}
public static Result absent(Throwable exception) {
return new AbsentResult(exception);
}
Result() {
// clients of the package can't extend this class
}
public abstract boolean isPresent();
public abstract T get();
public abstract Throwable getException();
}
class PresentResult extends Result {
private final T result;
public PresentResult(T result) {
this.result = result;
}
@Override
public boolean isPresent() {
return true;
}
@Override
public T get() {
return result;
}
@Override
public Throwable getException() {
throw new UnsupportedOperationException();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof PresentResult)) {
return false;
}
PresentResult other = (PresentResult) obj;
return Objects.equal(get(), other.get());
}
@Override
public int hashCode() {
return Objects.hashCode(get());
}
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("result", get())
.toString();
}
}
class AbsentResult extends Result {
private final Throwable exception;
public AbsentResult(Throwable exception) {
this.exception = exception;
}
@Override
public boolean isPresent() {
return false;
}
@Override
public Object get() {
throw new UnsupportedOperationException();
}
@Override
public Throwable getException() {
return exception;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
retu
Optional from Guava:```
public abstract class Result {
public static Result get(ResultType result) {
return new PresentResult(result);
}
public static Result absent(Throwable exception) {
return new AbsentResult(exception);
}
Result() {
// clients of the package can't extend this class
}
public abstract boolean isPresent();
public abstract T get();
public abstract Throwable getException();
}
class PresentResult extends Result {
private final T result;
public PresentResult(T result) {
this.result = result;
}
@Override
public boolean isPresent() {
return true;
}
@Override
public T get() {
return result;
}
@Override
public Throwable getException() {
throw new UnsupportedOperationException();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof PresentResult)) {
return false;
}
PresentResult other = (PresentResult) obj;
return Objects.equal(get(), other.get());
}
@Override
public int hashCode() {
return Objects.hashCode(get());
}
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("result", get())
.toString();
}
}
class AbsentResult extends Result {
private final Throwable exception;
public AbsentResult(Throwable exception) {
this.exception = exception;
}
@Override
public boolean isPresent() {
return false;
}
@Override
public Object get() {
throw new UnsupportedOperationException();
}
@Override
public Throwable getException() {
return exception;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
retu
Solution
Some remarks:
-
Why does
-
Is it on purpose that
-
Is it legal to initialize a
-
Why does
getException() return a Throwable instead of an Exception? Or even better, a RuntimeException? More generally, what is the purpose of this method? If I were you I'd "drop" it and make .get() throw the wanted exception instead. Since the exception would be a RuntimeException, there would be no need to declare it.-
Is it on purpose that
PresentResult and AbsentResult are not final? What do you expect further subclasses to extend if anything?-
Is it legal to initialize a
PresentResult with a null value, an AbsentResult with a null exception?Context
StackExchange Code Review Q#70025, answer score: 2
Revisions (0)
No revisions yet.