patternjavaMinor
Are there any issues in this `Lazy` implementation?
Viewed 0 times
thisareissuesanylazyimplementationthere
Problem
I have written following small utility to abstract away the lazy initialization logic. (I tend to use lazy variables quite often.)
Are there any issues in this implementation?
Edit:
Here is an example usage from the current project I am working on.
Are there any issues in this implementation?
// File: F0.java
public abstract class F0 {
public abstract A apply();
}
// File: Lazy.java
public class Lazy {
private boolean isInitialized = false;
private A content;
private final F0 init;
private Lazy(F0 init) {
this.init = init;
}
public static Lazy initializedAs(F0 init) {
return new Lazy(init);
}
@Override
public String toString() {
return this.get().toString();
}
public A get() {
if (!isInitialized) {
content = init.apply();
isInitialized = true;
}
return content;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Lazy lazy = (Lazy) o;
Object c = this.get();
if (c != null ? !c.equals(lazy.get()) : lazy.get() != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
return this.get().hashCode();
}
}Edit:
Here is an example usage from the current project I am working on.
final Prerequisite prerequisite = new Prerequisite() {
private Lazy minimumRequiredJavaVersion = Lazy.initializedAs(
new F0() {
@Override
public String apply() {
return SystemProperties.isWindows() && SystemProperties.is64Bit() ? "1.7" : "1.6";
}
}
);
@Override
public boolean isSatisfied() {
return SystemProperties.javaVersionIsMinimum(minimumRequiredJavaVersion.get());
}
@Override
public String failureMessage() {
StringBuilder sb = new StringBuilder();
sb.append("Minimum required Java version is: " + minimumRequiredJavaVersion.get() + "\n");
sb.append("Your system has " + JAVA_SPECIFICATION_VERSION + ".");
return sb.toString();
}
};Solution
Four notes:
-
It's not thread-safe.
-
The constructor should check
-
You should use
-
Instead of the anonymous
-
It's not thread-safe.
init.apply() could be called multiple times from different threads. (I don't know whether it is an issue or not.)-
The constructor should check
null inputs. (Effective Java 2nd Edition, Item 38: Check parameters for validity)-
You should use
append instead of String concatenation:StringBuilder sb = new StringBuilder();
sb.append("Minimum required Java version is: ").append(minimumRequiredJavaVersion.get()).append("\n");
sb.append("Your system has ").append(JAVA_SPECIFICATION_VERSION).append(".");
return sb.toString();-
Instead of the anonymous
Prerequisite inner class I'd use a named top-level class (for example, MinimumRequiredJavaVersionPrerequisite). I think it's easier to read, naming it helps readers to understand the purpose of the class.Code Snippets
StringBuilder sb = new StringBuilder();
sb.append("Minimum required Java version is: ").append(minimumRequiredJavaVersion.get()).append("\n");
sb.append("Your system has ").append(JAVA_SPECIFICATION_VERSION).append(".");
return sb.toString();Context
StackExchange Code Review Q#12250, answer score: 2
Revisions (0)
No revisions yet.