Why does this code not compile?
package sk.qpp.tmp.generics.simple;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.List;
import java.util.Optional;
@RequiredArgsConstructor
@Getter
// Why does simple commenting out of generics make code compilable? Intention is to use F generics for list of folders attribute
public class GSimpleFolder <F extends GSimpleFolder> {
private final String folderName;
private final List<GSimpleFolder> folders;
//private final List<F> folders;
public GSimpleFolder getParentAccordingPathToFileOrFolder(String path) {
final String[] pathSegments = path.split("/");
GSimpleFolder currentFolder = this;
// first part is name of root folder
for (int i = 1; i < pathSegments.length - 1; i++) {
final int finalVersionOfI = i;
currentFolder = currentFolder.getFolders().stream()
.filter(f -> 0 == pathSegments[finalVersionOfI].compareTo(f.getFolderName()))
.findFirst()
.orElse(null);
if (null == currentFolder) {
throw new RuntimeException("Folder \"" + pathSegments[finalVersionOfI] + "\" has not been found, when searching for parent folder for path \"" + path + "\". i=" + i);
}
}
return currentFolder;
}
}
Making GSimpleFolder not be generic (it is not using it now anywhere), compilation does work OK. Currently "f.getFolderName()" does claim, that f is of type Object and thus no method getFolderName can be called.
PS: Project with given problem can be found here: https://github.com/luvarqpp/InheritanceAndGenerics (it is playground for solving other problem too)
EDIT: Solution for this particular example is to not use RawType (i.e. class with generic, without specifying given generics). I have added all generics where needed, including in class definition.
package sk.qpp.tmp.generics.simple;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.List;
@RequiredArgsConstructor
@Getter
public class GSimpleFolder <F extends GSimpleFolder<F>> {
private final String folderName;
private final List<F> folders;
public F getParentAccordingPathToFileOrFolder(String path) {
final String[] pathSegments = path.split("/");
F currentFolder = (F) this;
// first part is name of root folder
for (int i = 1; i < pathSegments.length - 1; i++) {
final int finalVersionOfI = i;
currentFolder = currentFolder.getFolders().stream()
.filter(f -> 0 == pathSegments[finalVersionOfI].compareTo(f.getFolderName()))
.findFirst()
.orElse(null);
if (null == currentFolder) {
throw new RuntimeException("Folder \"" + pathSegments[finalVersionOfI] + "\" has not been found, when searching for parent folder for path \"" + path + "\". i=" + i);
}
}
return currentFolder;
}
}