我该如何向类型E倾倒,或者至少在没有警告的情况下以安全的方式进行操作? [英] How can I downcast to class' type E or at least make it in a safe way without warnings?

查看:105
本文介绍了我该如何向类型E倾倒,或者至少在没有警告的情况下以安全的方式进行操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有超级抽象类Node和50种子类SubNode。

我有一个通用类< E extends Node>其具有私有var List< E>和一个方法,不幸的是必须接受超类节点ALWAYS,不能将它移动到E:

  public void addSubElement(节点节点) {
if(node instanceOf E)subElements.add((E)node);
else //对偶尔的非E节点执行额外的步骤,例如在没有CastException的情况下静默放弃它们;
}

任何可以在没有警告的情况下编译的解决方案(Reflection?添加任何对象,由于类型擦除?? ...

我不想为任何类型的子类编写相同的函数:

  public void addSubElement(Node node){
if(node instanceOf SubNode1)subElements.add((SubNode1)node);
if(node instanceOf SubNode2)subElements.add((SubNode2)node);
// if(node instanceOf SubNode50 ....

它($)
$ b

  public void addSubElement(Node node){
subElements.add(( E)node.autoCastToSubClassOfAbstract(Node)); //如果非E
}


$ b,则抛出CastException $ b

  public void addSubElement(Node node){
subElements.add(node.autoCastTo E)); //如果非E
}应该抛出CastException


解决方案

编辑:所有其他答案的最终答案: 我接受titofb答案时犹豫不决,因为他是指定好方式的人,但我认为它应该针对我自己的问题(第一次),为了读者的利益。
$ b

抽象Node类实现了这一点:

  @SuppressWarnings(unchecked)
protected final Class< E> getChildType(){
return(Class< E>)(((ParameterizedType)getClass()。getGenericSuperclass())。getActualTypeArguments()[0]);





$ b因此,任何子节点总是有一个可用的方法,从定义中返回他自己的类型E
SubnodeN扩展节点< SubNodeX> (节点< E>中的子节点X = N)。这意味着我们可以在任何节点中执行此操作:

  public void addSubElement(Node <?> node){
Class< E> expectedChildType = getChildType();
if(expectedChildType.isAssignableFrom(node.getClass())){// if node instanceOf E
subElements.add(expectedChildType.cast(node));
}
else抛出新的ClassCastException(一个非预期的孩子打算添加到这个+ this.getClass()。getSimpleName()+element);
}

然后这就是魔术。这是默认行为。它警告你是否有一个孩子不被期待,但是你可以重写这个方法来处理任何特殊情况的子节点:

  @Override 
public void addSubElement(Node <?> node){
if(node instanceOf SubNode34){/ *是的,我们当前的子节点并不期望打算添加所有元素作为E类型节点,我们可以默默地放弃或做任何事情* /}
else super.addSubElement(node)//父母默认行为
}


I have super abstract class Node and 50 types of subclasses SubNode.

I have a generic Class <E extends Node> which has a private var List<E> and a method which unfortunately has to accept superclass Node ALWAYS, cannot move it to just E:

 public void addSubElement (Node node){ 
        if (node instanceOf E) subElements.add((E)node); 
        else //Doing extra steps for occasional non-E nodes like discarding them silently without CastException; 
 }

Any solution (Reflection?) able to compile without warnings, throwing a CastException instead of adding any object due to type erasure??...

I don´t want to have to write same function for any type of subclass:

 public void addSubElement (Node node){                             
        if (node instanceOf SubNode1) subElements.add((SubNode1)node); 
        if (node instanceOf SubNode2) subElements.add((SubNode2)node); 
        //if (node instanceOf SubNode50....
 }

It would be so nice having a method like.

public void addSubElement (Node node){ 
        subElements.add((E)node.autoCastToSubClassOfAbstract("Node")); //Should throw CastException if non-E
 }

or

 public void addSubElement (Node node){ 
        subElements.add(node.autoCastTo("E")); //Should throw CastException if non-E
 }

解决方案

EDIT: FINAL ANSWER FROM ALL OTHER ANSWERS:

I was hesitating if accepting titofb answer, beause he is the one who appointed the good way. But I think it is enough targeted on y problem that should acept my own (for very 1st time), for the benefit of others who read it. Thanks to all!

Abstract Node class implements this:

    @SuppressWarnings("unchecked")
    protected final Class<E> getChildType(){
        return (Class<E>)(((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]); 
    }

So any Subnode has always an available method which returns his own Type E from definition SubnodeN extends Node<SubNodeX> (SubnodeX = N in Node<E>). That means that we can do that in any node:

 public void addSubElement (Node<?> node){ 
      Class<E> expectedChildType = getChildType();
      if (expectedChildType.isAssignableFrom(node.getClass())){//if node instanceOf E
         subElements.add(expectedChildType.cast(node)); 
      }
      else throw new ClassCastException("A non-expected child was intended to add to this "+this.getClass().getSimpleName()+" element");
 }

And then here it is the magic. This is the default behavior. It warns you if some child was not expected, but you can override this method for any subnode for handling special cases:

 @Override
 public void addSubElement (Node<?> node){ 
      if (node instanceOf SubNode34) {/* Yes, our current subnode does not expect all elements intended to be added as E type nodes, we can silently discard or do whatever */}
      else super.addSubElement(node) //Parents default behavior
 }    

这篇关于我该如何向类型E倾倒,或者至少在没有警告的情况下以安全的方式进行操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆