Java 更正将对象添加到方法中列表的泛型类型
我有一系列的形状(Java 更正将对象添加到方法中列表的泛型类型,java,generics,Java,Generics,我有一系列的形状(SVGShape),希望使用一种方法将它们添加到列表中(这将执行更多逻辑)。用于添加SVGCircle的代码可以工作,但会重复。SVGEllipse的代码代表了我想要做的事情,因此有一个方法不知道传递的是哪种类型,但无法编译。一般类型是(我认为)List如果您将方法的签名更改为void addToListAndSetId(List如果您将方法的签名更改为void addToListAndSetId(List),您可能希望使用泛型 private <T extends SV
SVGShape
),希望使用一种方法将它们添加到列表中(这将执行更多逻辑)。用于添加SVGCircle
的代码可以工作,但会重复。SVGEllipse
的代码代表了我想要做的事情,因此有一个方法不知道传递的是哪种类型,但无法编译。一般类型是(我认为)List如果您将方法的签名更改为void addToListAndSetId(List如果您将方法的签名更改为void addToListAndSetId(List),您可能希望使用泛型
private <T extends SVGShape> void addToListAndSetId(List<T> shapeList, T shape) {
shapeList.add(shape); // more logic here
shape.setId(shape.getLocalName().toLowerCase() + shapeList.size());
}
private void addToListAndSetId(列表形状列表,T形){
shapeList.add(shape);//这里有更多的逻辑
setId(shape.getLocalName().toLowerCase()+shapeList.size());
}
您可能希望使用泛型
private <T extends SVGShape> void addToListAndSetId(List<T> shapeList, T shape) {
shapeList.add(shape); // more logic here
shape.setId(shape.getLocalName().toLowerCase() + shapeList.size());
}
private void addToListAndSetId(列表形状列表,T形){
shapeList.add(shape);//这里有更多的逻辑
setId(shape.getLocalName().toLowerCase()+shapeList.size());
}
编辑:在函数中强制类型匹配的更好方法是使用T extends SVGShape
,正如他在回答中提到的,因此函数void addToListAndSetId2(List List List,T shape)
是一个更好的解决方案,因为不匹配的参数将不会编译(根据需要):
//列出日食;
//SVG圆;
addToListAndSetId2(日食,圆圈);//这将不会按要求编译
//列出日食;
//SVG圆;
addToListAndSetId(日食,圆圈);//这将编译,但不应编译
----编辑前:
您应该创建泛型类型的列表,而不是
List,List
使用泛型类或接口,如List或List
下面是在编译时工作的代码片段。我还列出了根据您的问题详细信息假设的其他类:
public static void main(String []args) {
List<SVGShape> shapes = new ArrayList<>();
// cirlce list of generic type
List<SVGShape> circleList = new ArrayList<>();
// eclipse list fof generic type
List<SVGShape> ecliplseList = new ArrayList<>();
for(SVGShape shape: shapes) {
if(shape instanceof SVGCircle) {
SVGCircle svgCircle = (SVGCircle) shape;
svgCircle.setId("some-id");
circleList.add(svgCircle);
addToListAndSetId(circleList, svgCircle);
} else if(shape instanceof SVGEcliplse){
SVGEcliplse ecliplse = (SVGEcliplse) shape;
ecliplseList.add(ecliplse);
addToListAndSetId(ecliplseList, ecliplse);
}
}
}
// This does not force both params to be of same type
public static void addToListAndSetId(List<SVGShape> shapeList, SVGShape shape) {
shapeList.add(shape);
if(shape instanceof SVGCircle) {
shape.setId("some-circle-id");
} else if(shape instanceof SVGEcliplse) {
shape.setId("some-eclipse-id");
}
}
// This DOES force both params (shapelist type and shape type) to be of same type
public <T extends SVGShape> void addToListAndSetId2(List<T> shapeList, T shape) {
shapeList.add(shape);
shape.setId("some-id");
}
public class SVGCircle extends SVGShape {
}
public class SVGEcliplse extends SVGShape {
}
public class SVGShape implements ISVGShape {
public void setId(String id) {
// some logic
}
}
public interface ISVGShape {
}
publicstaticvoidmain(字符串[]args){
列表形状=新建ArrayList();
//泛型类型的循环列表
List circleList=新建ArrayList();
//泛型类型的eclipse列表
List ECLIPLESLIST=新建ArrayList();
用于(SVG形状:形状){
if(SVGCircle的形状实例){
SVGCircle SVGCircle=(SVGCircle)形状;
svgCircle.setId(“某些id”);
圆圈列表。添加(svgCircle);
addToListAndSetId(圆圈列表,svgCircle);
}else if(SVGEcliplse的形状实例){
SVGEcliplse ecliplse=(SVGEcliplse)形状;
添加(ecliplse);
addToListAndSetId(ECLIPLESLIST,ECLIPLESE);
}
}
}
//这并不强制两个参数为同一类型
公共静态void addToListAndSetId(列表形状列表、SVGShape形状){
添加(形状);
if(SVGCircle的形状实例){
shape.setId(“某个圆id”);
}else if(SVGEcliplse的形状实例){
setId(“某些eclipse id”);
}
}
//这会强制两个参数(shapelist类型和shape类型)的类型相同
公共void addToListAndSetId2(列表形状列表,T形){
添加(形状);
shape.setId(“某些id”);
}
公共类SVGCircle扩展了SVGShape{
}
公共类SVGEcliplse扩展了SVGShape{
}
公共类SVGShape实现了ISVGShape{
公共无效集合id(字符串id){
//一些逻辑
}
}
公共接口ISVGShape{
}
编辑:在函数中强制类型匹配的更好方法是使用T extends SVGShape
,正如他在回答中提到的,因此函数void addToListAndSetId2(List List List,T shape)
是一个更好的解决方案,因为不匹配的参数将不会编译(根据需要):
//列出日食;
//SVG圆;
addToListAndSetId2(日食,圆圈);//这将不会按要求编译
//列出日食;
//SVG圆;
addToListAndSetId(日食,圆圈);//这将编译,但不应编译
----编辑前:
您应该创建泛型类型的列表,而不是
List,List
使用泛型类或接口,如List或List
下面是在编译时工作的代码片段。我还列出了根据您的问题详细信息假设的其他类:
public static void main(String []args) {
List<SVGShape> shapes = new ArrayList<>();
// cirlce list of generic type
List<SVGShape> circleList = new ArrayList<>();
// eclipse list fof generic type
List<SVGShape> ecliplseList = new ArrayList<>();
for(SVGShape shape: shapes) {
if(shape instanceof SVGCircle) {
SVGCircle svgCircle = (SVGCircle) shape;
svgCircle.setId("some-id");
circleList.add(svgCircle);
addToListAndSetId(circleList, svgCircle);
} else if(shape instanceof SVGEcliplse){
SVGEcliplse ecliplse = (SVGEcliplse) shape;
ecliplseList.add(ecliplse);
addToListAndSetId(ecliplseList, ecliplse);
}
}
}
// This does not force both params to be of same type
public static void addToListAndSetId(List<SVGShape> shapeList, SVGShape shape) {
shapeList.add(shape);
if(shape instanceof SVGCircle) {
shape.setId("some-circle-id");
} else if(shape instanceof SVGEcliplse) {
shape.setId("some-eclipse-id");
}
}
// This DOES force both params (shapelist type and shape type) to be of same type
public <T extends SVGShape> void addToListAndSetId2(List<T> shapeList, T shape) {
shapeList.add(shape);
shape.setId("some-id");
}
public class SVGCircle extends SVGShape {
}
public class SVGEcliplse extends SVGShape {
}
public class SVGShape implements ISVGShape {
public void setId(String id) {
// some logic
}
}
public interface ISVGShape {
}
publicstaticvoidmain(字符串[]args){
列表形状=新建ArrayList();
//泛型类型的循环列表
List circleList=新建ArrayList();
//泛型类型的eclipse列表
List ECLIPLESLIST=新建ArrayList();
用于(SVG形状:形状){
if(SVGCircle的形状实例){
SVGCircle SVGCircle=(SVGCircle)形状;
svgCircle.setId(“某些id”);
圆圈列表。添加(svgCircle);
addToListAndSetId(圆圈列表,svgCircle);
}else if(SVGEcliplse的形状实例){
SVGEcliplse ecliplse=(SVGEcliplse)形状;
添加(ecliplse);
addToListAndSetId(ECLIPLESLIST,ECLIPLESE);
}
}
}
//这并不强制两个参数为同一类型
公共静态void addToListAndSetId(列表形状列表、SVGShape形状){
添加(形状);
if(SVGCircle的形状实例){
shape.setId(“某个圆id”);
}else if(SVGEcliplse的形状实例){
setId(“某些eclipse id”);
}
}
//这会强制两个参数(shapelist类型和shape类型)的类型相同
公共void addToListAndSetId2(列表形状列表,T形){
添加(形状);
shape.setId(“某些id”);
}
公共类SVGCircle扩展了SVGShape{
}
公共类SVGEcliplse扩展了SVGShape{
}
公共类SVGShape实现了ISVGShape{
公共无效集合id(字符串id){
//一些逻辑
}
}
//List<SVGEclipse> eclipses;
//SVGCircle circle;
addToListAndSetId2(eclipses, circle); // this will not compile as required
//List<SVGShape> eclipses;
//SVGCircle circle;
addToListAndSetId(eclipses, circle); // this will compile although should NOT
public static void main(String []args) {
List<SVGShape> shapes = new ArrayList<>();
// cirlce list of generic type
List<SVGShape> circleList = new ArrayList<>();
// eclipse list fof generic type
List<SVGShape> ecliplseList = new ArrayList<>();
for(SVGShape shape: shapes) {
if(shape instanceof SVGCircle) {
SVGCircle svgCircle = (SVGCircle) shape;
svgCircle.setId("some-id");
circleList.add(svgCircle);
addToListAndSetId(circleList, svgCircle);
} else if(shape instanceof SVGEcliplse){
SVGEcliplse ecliplse = (SVGEcliplse) shape;
ecliplseList.add(ecliplse);
addToListAndSetId(ecliplseList, ecliplse);
}
}
}
// This does not force both params to be of same type
public static void addToListAndSetId(List<SVGShape> shapeList, SVGShape shape) {
shapeList.add(shape);
if(shape instanceof SVGCircle) {
shape.setId("some-circle-id");
} else if(shape instanceof SVGEcliplse) {
shape.setId("some-eclipse-id");
}
}
// This DOES force both params (shapelist type and shape type) to be of same type
public <T extends SVGShape> void addToListAndSetId2(List<T> shapeList, T shape) {
shapeList.add(shape);
shape.setId("some-id");
}
public class SVGCircle extends SVGShape {
}
public class SVGEcliplse extends SVGShape {
}
public class SVGShape implements ISVGShape {
public void setId(String id) {
// some logic
}
}
public interface ISVGShape {
}