Java 在这种情况下如何避免泛型? 类属性{ 私人旅行社; 公共属性(T属性){ this.attr=attr; } } 类矩阵{ 私有字符串名称; 名单; 公共矩阵(字符串名称,T){ this.name=名称; 列表=新的ArrayList(); 添加(新属性(t)); } } 接口提取器{ 公共列表摘录(); } InfoExtractor实现了提取器{ 公共列表提取(){ List matrixList=新建ArrayList(); //问题就在这里!!!! 矩阵列表。添加(新矩阵(“abc”); } } 文件{ 地图矩阵图; 公共程序(){ ... 提取器提取器=(提取器)新字符串提取器(已发送); 列表矩阵=extractor.extract(…); }
我的问题是,有没有办法避免将矩阵定义为泛型类型?我想避免的原因是“Java 在这种情况下如何避免泛型? 类属性{ 私人旅行社; 公共属性(T属性){ this.attr=attr; } } 类矩阵{ 私有字符串名称; 名单; 公共矩阵(字符串名称,T){ this.name=名称; 列表=新的ArrayList(); 添加(新属性(t)); } } 接口提取器{ 公共列表摘录(); } InfoExtractor实现了提取器{ 公共列表提取(){ List matrixList=新建ArrayList(); //问题就在这里!!!! 矩阵列表。添加(新矩阵(“abc”); } } 文件{ 地图矩阵图; 公共程序(){ ... 提取器提取器=(提取器)新字符串提取器(已发送); 列表矩阵=extractor.extract(…); },java,generics,Java,Generics,我的问题是,有没有办法避免将矩阵定义为泛型类型?我想避免的原因是“列表””在多个其他类中使用,或者作为私有成员变量,或者作为方法返回类型。由于属性的原因,似乎我也必须将一些其他相关类定义为泛型类型,这导致了我的问题 在这种情况下,是否有办法不将矩阵定义为泛型,而将“list”变量保留为泛型类型?这取决于您希望执行的操作 如果您打算使用矩阵来保存单一类型的属性,那么最好的方法似乎是在编译时进行类型检查时发布的方法 如果从矩阵中删除泛型类型T,则无法知道每个属性的类型。可以从矩阵声明中完全删除T,并
列表”
”在多个其他类中使用,或者作为私有成员变量,或者作为方法返回类型。由于属性的原因,似乎我也必须将一些其他相关类定义为泛型类型,这导致了我的问题
在这种情况下,是否有办法不将矩阵定义为泛型,而将“list”变量保留为泛型类型?这取决于您希望执行的操作 如果您打算使用矩阵来保存单一类型的属性,那么最好的方法似乎是在编译时进行类型检查时发布的方法 如果从矩阵中删除泛型类型T,则无法知道每个属性的类型。可以从矩阵声明中完全删除T,并对属性变量使用通配符。虽然这将允许您在同一矩阵对象中存储不同T类型的属性,但它将删除编译类型检查。换句话说,使用矩阵的类必须知道期望的类,并且可能将每个属性强制转换为期望的类
class Attribute<T>{
private T attr;
public Attribute(T attr){
this.attr = attr;
}
}
Class Matrix<T>{
private String name;
List<Attribute<T>> list;
public Matrix(String name, T t){
this.name = name;
list = new ArrayList<>();
list.add(new Attribute<T>(t));
}
}
interface Extractor<T> {
public List<Matrix<T>> extract();
}
InfoExtractor implements Extractor<String>{
public List<Matrix<String>> extract(){
List<Matrix<String>> matrixList = new ArrayList<>();
// The problem is here!!!!
matrixList.add(new Matrix<String>("abc"));
}
}
Document<T>{
Map<String, List<Matrix<T>>> matrixMap;
public void process(){
...
Extractor<T> extractor = (Extractor<T>) new StringExtractor(sent);
List<Matrix<T>> matrix = extractor.extract(...);
}
类矩阵{
私有字符串名称;
List您的问题不在于通用实现,而在于其用法:
class Attribute<T>{
private T attr;
private final Class<T> clazz;
public Attribute(T attr, Class<T> clazz){
this.attr = attr;
this.clazz=clazz;
}
public Attribute(T attr){
this.attr = attr;
Objects.requireNonNull(attr);
this.clazz= (Class<T>) attr.getClass();
}
}
当然,您可以看到
提取器的方法签名已更改。由于在返回类型上使用嵌套泛型,在编译时进行类型匹配时会有点混乱。矩阵的
非常简单,我们在矩阵中返回多个可能未知的类型
通过在提取器
上指定?扩展矩阵
,我们指定了适当的方差。具体的泛型是不变的,因此列表
不是列表
,即使丰田
是汽车
的子类。如果我们希望矩阵
是协变的,那么我们需要矩阵a上的边界很遗憾,这意味着实际上,忽略Liskov的替换原则,我们基本上会引用提取器的具体子类(InfoExtractor ex
vsExtractor ex
),特别是从可用性的角度来看(因为具体类可以返回适当的类型安全性,而接口不能)
当然,当您将列表中矩阵的
指定为类级泛型类型时,处理起来更为理智/干净。然后您必须决定列表变量的泛型类型。必须指定某些类型,因此在编写矩阵m=new Matrix()时
,您希望列表的类型是什么?列表
?显示您如何使用此泛型代码。本质上那里的泛型没有问题(属性几乎是一个美化的包装,不需要),你基本上有矩阵
,这是一个带有名称的列表
。请参阅我的补充。在矩阵中有一些关于方法签名的信息会很有帮助。这可以通过指定clazz必须是类
而不是类
来改进。帖子按照com中的指示进行了更新区别不大,因为T在运行时会丢失,所以T不能以某种方式使用。但是,阅读代码更容易。如果查看文档,List matrix=extractor.extract(…);我必须从一个列表转换到另一个列表,这正是我试图避免的。请参阅Document.process方法。您仍然剪掉了太多的代码。您引用了我们没有提供的提取器
变量,并且在文档不一定需要的情况下基本上是在生成文档。您试图实现什么通过这样做,您可以获得什么样的信息?请记住,如果类型不匹配,您就没有列表
您有一个列表
由于变量“Map matrixMap;”您可以看到列表。实际上,我不会同时将不同的类型存储到列表中。对于同一个列表对象,列表存储相同类型的矩阵。对,但是您映射了什么?以及什么是提取器
(InfoExtractor实例?)?最后,我认为您正在寻找通配符,而不是类级别的泛型。因此基本上,list是通配符方式矩阵的良好实践吗?我担心的是,我的列表对象应该始终为相同的列表存储相同类型的对象。
class Attribute<T>{
private T attr;
private final Class<T> clazz;
public Attribute(T attr, Class<T> clazz){
this.attr = attr;
this.clazz=clazz;
}
public Attribute(T attr){
this.attr = attr;
Objects.requireNonNull(attr);
this.clazz= (Class<T>) attr.getClass();
}
}
class InfoExtractor implements Extractor{
// The problem is actually here
public <T> List<Matrix<T>> extract(){
List<Matrix<T>> matrixList = new ArrayList<>(); //and here
// "The problem is here!!!!"
matrixList.add(new Matrix<String>("abc"));
}
}
//If you cannot generify the interface for some reason
interface Extractor {
public List<? extends Matrix<?>> extract(); //explained at bottom
}
//IDEALLY, then implement Extractor<String> instead
interface Extractor<T> {
public List<Matrix<T>> extract();
}
class InfoExtractor implements Extractor { //or Extractor<String>
public List<Matrix<String>> extract() {
List<Matrix<String>> matrixList = new ArrayList<>();
matrixList.add(new Matrix<>("abc"));
return matrixList;
}
}