Java 泛型类中的静态final变量导致未选中&;原始类型警告

Java 泛型类中的静态final变量导致未选中&;原始类型警告,java,generics,Java,Generics,在泛型类中有静态final变量是设计缺陷吗?考虑下面的类,所有引用“代码>节点”。解决这个问题的好方法是什么 public class Node<E> { private static int nodeCounter = 0; @SuppressWarnings({ "unchecked", "rawtypes" }) public static final Node SOIL = new Node(null, null); // <-- HER

在泛型类中有静态final变量是设计缺陷吗?考虑下面的类,所有引用“代码>节点”。解决这个问题的好方法是什么

public class Node<E> {

    private static int nodeCounter = 0;

    @SuppressWarnings({ "unchecked", "rawtypes" })  
    public static final Node SOIL = new Node(null, null); // <-- HERE
    public static void resetSOIL(){
        SOIL.children = null; // <-- HERE
    }

    private Node<E> parent;
    private Set<Node<E>> children;

    protected Set<Node<E>> isomorphs;
    private E data;
    private int id;

    public Node(Node<E> parent, E data){
        this.parent = parent;
        this.data = data;
        this.id = ++nodeCounter;

    }

    public boolean isRoot(){
        return (this.getParent() == SOIL);
    }

    // utility methods
    ....
}
公共类节点{
私有静态int nodeCounter=0;
@SuppressWarnings({“unchecked”,“rawtypes”})

public static final Node SOIL=new Node(null,null);//具有静态final变量不是设计缺陷。出现警告是因为您在声明泛型类型的实例时未提供类型参数:

public static final Node SOIL = new Node(null, null); // <-- HERE

publicstaticfinalnode-SOIL=new-Node(null,null);//您可以使用此选项来避免SuppressWarning,并且效果良好:

private static final Node<Object> SOIL = new Node<Object>(null, null);

没有itsnt,使用它作为Node类型的空变量的默认值甚至是一种很好的常见做法,也称为有效Java编程中的空对象

您定义了一个类型
节点
,它表示E树中的一个节点。例如,
节点
是整数树中的一个节点,
节点
是数据树中的一个节点字符串

现在,您需要一个变量
SOIL
,它包含这些不同类型的树的所有根(呵呵,SOIL,我现在就知道了)。暂时搁置静态字段问题。SOIL
的类应该是什么?换句话说,我们如何声明和创建
SOIL
实例

Node</*something1*/> SOIL = new Node</*something2*/>(null, null);
(如果使用Java 7菱形构造
新节点(…)
在本例中,它最终使用
对象

问题是,这仍然不起作用。
节点
类型的定义方式是E的同构树。但是
土壤
的一个子树是整数树,另一个子树是字符串树,因此
土壤
希望成为异构树。因此,
土壤
不能成为任何
E
节点

至少,不是以一种类型安全的方式。你可以编写代码来做这件事,但是你必须添加一些转换,你会得到未经检查的警告。这些警告会告诉你这个方法不起作用。例如,考虑一些代码,使用代码< <节点>代码>,并对其所有兄弟姐妹进行操作。(也就是说,它的父节点的其他子节点)。使用

节点
的一些代码可以调用它,并最终得到一堆
节点
的实例,然后开始抛出
类异常


你可以考虑制作<代码>土壤<代码> A<代码> StId:你真的需要土壤是静态的吗?土壤会对你所有的节点实例产生影响,这是预期的行为吗?它是一个设计缺陷,具有全局状态(可变的静态)。@assyl还有一个想法,就是要有一个所有类型节点的母亲,我相信这就是

SOIL
的好处?
resetSOIL()
的存在是为了避免在运行单元测试时出现恼人的问题(以前测试中的所有节点都保留在
SOIL
中,否则)@TomHawtin大头钉即使它最终确定了?嗯,再想想,土壤是最终的这一事实并不意味着它不能变异,事实上它确实变异了(得到了孩子)…@posdef是的,的确如此。全局状态通常通过初始静态引用
final
潜入雷达之下,然后指向一些可变的东西。问题是在
节点
类中,我不知道运行时
E
将是什么,这就是为什么我一开始就为泛型而烦恼的原因。所以我不能真正确定SOIL是否使用了
SomeType
。或者我误解了你的建议?@posdef:那么,如果这个
节点
实例不能接受任何类型参数,你想对它做什么呢?正如我在上面的一篇评论中提到的,这个想法是让所有类型节点都有一个母节点,而不管节点层次结构中携带的实际数据类型是什么。@posdef:我想你可以使用
节点
来避免警告。我不知道这是你需要的。
Is it a design flaw to have a static final variable in a generic class?
Node</*something1*/> SOIL = new Node</*something2*/>(null, null);
Node<?> SOIL = new Node<Object>(null, null);