提问人:mepmerp 提问时间:11/9/2022 更新时间:11/10/2022 访问量:117
Java 未选中从包含通配符的列表转换为特定类型的列表
Java Unchecked Cast from List containing wildcard to List of a specific type
问:
我有以下课程
public class PathPart {
private final String pathPart;
public PathPart(String pathPart) {
this.pathPart = pathPart;
}
public String getPathPart() {
return pathPart;
}
}
public class Path {
private final List<? extends PathPart> pathParts;
public Path(String path) {
this.pathParts = getPathParts(path);
}
public List<? extends PathPart> getPathParts() {
return this.pathParts;
}
protected List<? extends PathPart> getPathParts(String path) {
return Arrays.stream(path.split("/")).map(PathPart::new).collect(Collectors.toList());
}
}
public class FooBarPathPart extends PathPart {
public FooBarPathPart(String pathPart) {
super(isFoo(pathPart) ? "bar" : pathPart);
}
private static boolean isFoo(String pathPart) {
return "foo".equals(pathPart);
}
}
public class FooBarPath extends Path {
public FooBarPath(String path) {
super(path);
}
@Override
public List<FooBarPathPart> getPathParts() {
// UNCHECKED CAST HERE
return (List<FooBarPathPart>) super.getPathParts();
}
@Override
protected List<FooBarPathPart> getPathParts(String path) {
return Arrays.stream(path.split("/")).map(FooBarPathPart::new).collect(Collectors.toList());
}
}
我想在我的对象中捕获文件系统路径的结构,该路径将 、 、 、 每个存储为一个对象。/my/path/to/a/directory
Path
my
path
to
a
directory
PathPart
现在,我有一个子类 called ,其中如果路径部分等于 ,那么我希望它更改为 。而且,我还有 which 是 的子类,它存储了 的列表。所以本质上会成为PathPart
FooBarPathPart
foo
bar
FooBarPath
Path
FooBarPathPart
/my/path/to/foo/directory
/my/path/to/bar/directory
我的问题是我在类中的方法中收到来自 to 的警告。Unchecked cast
List<? extends PathPart>
List<FooBarPath>
getPathParts()
FooBarPath
有没有办法正确摆脱这种未经检查的投射警告?我在这里使用通配符是否正确?或者有没有更好的方法来解决这个问题而不涉及通配符?我对泛型不是很熟悉
答:
0赞
mepmerp
11/10/2022
#1
感谢托马斯的帮助
我已经使用泛型和创建者函数解决了这个问题。以下是完整的解决方案:
public class PathPart {
private final String pathPart;
public PathPart(String pathPart) {
this.pathPart = pathPart;
}
public String getPathPart() {
return pathPart;
}
}
public class FooBarPathPart extends PathPart {
public FooBarPathPart(String pathPart) {
super(isFoo(pathPart) ? "bar" : pathPart);
}
private static boolean isFoo(String pathPart) {
return "foo".equals(pathPart);
}
}
public abstract class AbstractPath<T extends PathPart> {
private final List<T> pathParts;
private final Function<String, T> factory;
public AbstractPath(Function<String, T> factory, String path) {
this.factory = factory;
this.pathParts = createPathParts(path);
}
public List<T> createPathParts() {
return this.pathParts;
}
private List<T> createPathParts(String path) {
return Arrays.stream(path.split("/")).map(factory).collect(Collectors.toList());
}
}
public class Path extends AbstractPath<PathPart> {
public Path(String path) {
super(PathPart::new, path);
}
}
public class FooBarPath extends AbstractPath<FooBarPathPart> {
public FooBarPath(String path) {
super(FooBarPathPart::new, path);
}
}
评论
class Path<T extends PathPart> { private final List<T> pathParts; ... }
class FooBarPath extends Path<FooBarPathPath>{ ... }
Path
pathParts
PathPart
return Arrays.stream(path.split("/")).map(PathPart::new).collect(Collectors.toList());
Path
new Path("/some/path")
PathPart
Path
FooBarPath