gpt4 book ai didi

Java 通用对象重用

转载 作者:行者123 更新时间:2023-12-01 19:33:16 26 4
gpt4 key购买 nike

我有一个类层次结构,并且想为层次结构中的每个类构建属性 setter 列表。我要编写的代码类似于以下内容:

import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;

class Attribute<E, T> {
public final Class<T> dataType;
public final BiConsumer<E, T> setter;
public Attribute(final Class<T> dataType, final BiConsumer<E, T> setter) {
this.dataType = dataType;
this.setter = setter;
}
}

class Foo1 {
public static final List<Attribute<Foo1, ?>> foo1Attrs = new ArrayList<>();
static {
foo1Attrs.add(new Attribute<>(String.class, Foo1::setProp1));
}
public void setProp1(final String prop1) {
}
}

class Foo2 extends Foo1 {
// The following line results in an error
public static final List<Attribute<Foo2, ?>> foo2Attrs = new ArrayList<>(foo1Attrs);
static {
foo2Attrs.add(new Attribute<>(Integer.class, Foo2::setProp2));
}
public void setProp2(final Integer prop2) {
}
}

当我编译上面的代码时,出现错误:

error: incompatible types: cannot infer type arguments for ArrayList<>  public static final List<Attribute<Foo2, ?>> foo2Attrs = new ArrayList<>(foo1Attrs);                                                                          ^  reason: inference variable E has incompatible bounds    equality constraints: Attribute<Foo2,?>    lower bounds: Attribute<Foo1,?>where E is a type-variable:  E extends Object declared in class ArrayList

I understand why I am getting the above error. My question is, what is the typically pattern employed to make the above code compile and run?

The only way I can figure out how to make this work is to create a copy constructor on the Attribute class that takes an Attribute<? extends E, T>, then duplicate the data members (pointers) stored in the Attribute class into a second memory location with a different type. This seems really heavy for what should be the equivalent of a static_cast in C++. The following changes exemplify this approach:

class Attribute<E, T> {
...
public final BiConsumer<? super E, T> setter;
...
public Attribute(final Attribute<? super E, T> other) {
this.dataType = other.dataType;
this.setter = other.setter;
}
}

class Foo2 extends Foo1 {
public static final List<Attribute<Foo2, ?>> foo2Attrs = new ArrayList<>();
static {
for (Attribute<Foo1, ?> attr : foo1Attrs)
foo2Attrs.add(new Attribute<>(attr));
...
}
...
}

重申一下这个问题:是否有比上述方法更好的方法来解决此编译时错误?

最佳答案

foo2Attrs可以包含Attribute<Foo1, ?>哪里Foo1Foo2 的父类(super class)型,它应该声明为类型 List<Attribute<? super Foo2, ?>> 。这是有道理的,因为 Foo2对象可以由任何针对 Foo2 父类(super class)的属性 setter 设置其属性。 .

同样,foo1Attrs应声明为类型 List<Attribute<? super Foo1, ?>> .

这消除了由第一个类型参数引起的编译错误,但是当您尝试编写像foo2Attrs.get(i).setter.accept(foo, 23)这样的代码时仍然会出现问题。 ,因为setter被推断为类型 BiConsumer<? super Foo2, ?>和整数 23无法转换为第二个? .

关于Java 通用对象重用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58828375/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com