-
Notifications
You must be signed in to change notification settings - Fork 411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
error message about not initialized field is not correct #2929
Comments
looks like an upstream bug from the Eclipse compiler. @snjeza can you confirm? |
I can reproduce the issue in the jdt master branch and javac. jdt returns
javac returns
|
I can confirm, that javac returns that error. But I don't understand, why this error message appears. I tested with an explicitly written constructor(in case lombok is not working correctly), but the error message remains the same. |
I don't think this is a bug at all. You need to initialize the
So when you are using At least, that's my analysis of the situation, based on what I've read online 🙂. Take it with a grain of salt, I'm not a JLS expert. You have already found a solution to the problem (using a method instead of a lambda in a field). Here are a few other potential solutions I could think of: 1: Initialize import java.util.stream.Collector;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class MergePatchesCollector
implements Collector<String, List<String>, List<String>> {
private final static Pattern partsPattern =
Pattern.compile("(provides|internal|external|softwareDependencies)");
private final Map<String, Long> nrOfNodesPerPart = null; // TODO: Initialize to a better value?
private Function<String, Long> getNrOfNodesForPart = (path) -> {
if (path == null || path.isEmpty() || path.isBlank()) {
return 0L;
}
Matcher partsMatcher = partsPattern.matcher(path);
if (partsMatcher.find()) {
return nrOfNodesPerPart.getOrDefault(partsMatcher.group(), Long.valueOf(0l)).longValue();
}
return 0L;
};
} 2: Initialize import java.util.stream.Collector;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public class MergePatchesCollector
implements Collector<String, List<String>, List<String>> {
private final static Pattern partsPattern =
Pattern.compile("(provides|internal|external|softwareDependencies)");
private final Map<String, Long> nrOfNodesPerPart;
private Function<String, Long> getNrOfNodesForPart;
public MergePatchesCollector(Map<String, Long> nrOfNodesPerPart) {
this.nrOfNodesPerPart = nrOfNodesPerPart;
this.getNrOfNodesForPart = (path) -> {
if (path == null || path.isEmpty() || path.isBlank()) {
return 0L;
}
Matcher partsMatcher = partsPattern.matcher(path);
if (partsMatcher.find()) {
return this.nrOfNodesPerPart.getOrDefault(partsMatcher.group(), Long.valueOf(0l)).longValue();
}
return 0L;
};
}
} 3: Use an anonymous class instead (where import java.util.stream.Collector;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class MergePatchesCollector
implements Collector<String, List<String>, List<String>> {
private final static Pattern partsPattern =
Pattern.compile("(provides|internal|external|softwareDependencies)");
private final Map<String, Long> nrOfNodesPerPart;
private Function<String, Long> getNrOfNodesForPart = new Function<String, Long>() {
@Override
public Long apply(String path) {
if (path == null || path.isEmpty() || path.isBlank()) {
return 0L;
}
Matcher partsMatcher = partsPattern.matcher(path);
if (partsMatcher.find()) {
return nrOfNodesPerPart.getOrDefault(partsMatcher.group(), Long.valueOf(0l)).longValue();
}
return 0L;
}
};
} 4: Use a method, but also create a field using a method reference (if the field was important to you): import java.util.stream.Collector;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class MergePatchesCollector
implements Collector<String, List<String>, List<String>> {
private final static Pattern partsPattern =
Pattern.compile("(provides|internal|external|softwareDependencies)");
private final Map<String, Long> nrOfNodesPerPart;
private Function<String, Long> getNrOfNodesForPart = this::getNrOfNodesForPart;
private long getNrOfNodesForPart(String path) {
if (path == null || path.isEmpty() || path.isBlank()) {
return 0L;
}
Matcher partsMatcher = partsPattern.matcher(path);
if (partsMatcher.find()) {
return nrOfNodesPerPart.getOrDefault(partsMatcher.group(), 0L);
}
return 0L;
}
} 5: Bypass compiler checks using a local variable: import java.util.stream.Collector;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class MergePatchesCollector
implements Collector<String, List<String>, List<String>> {
private final static Pattern partsPattern =
Pattern.compile("(provides|internal|external|softwareDependencies)");
private final Map<String, Long> nrOfNodesPerPart;
private Function<String, Long> getNrOfNodesForPart = (path) -> {
if (path == null || path.isEmpty() || path.isBlank()) {
return 0L;
}
Matcher partsMatcher = partsPattern.matcher(path);
if (partsMatcher.find()) {
MergePatchesCollector mpc = this;
// this.nrOfNodesPerPart is still potentially uninitialized, but the compiler doesn't understand that mpc == this
return mpc.nrOfNodesPerPart.getOrDefault(partsMatcher.group(), Long.valueOf(0l)).longValue();
}
return 0L;
};
} |
Wow! Thank you very much for your very detailed answer, @0dinD ! Your excerpt explains it very good, why this is not a bug. I had this suspicion, that this is not a bug, but I really couldn't explain it for myself. But yes, |
Hi,
in the following snippet, I get the following error message at line
return nrOfNodesPerPart.getOrDefault(partsMatcher.group(), Long.valueOf(0l)).longValue();
:If I rewrite as a function, the error message disappears:
In my opinion, the error message in the first case doesn't make sense, because the field is initialized via the constructor or do I oversee something?
The text was updated successfully, but these errors were encountered: