Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在这段代码中有没有避免@SuppressWarnings的方法?_Java_Arrays_Generics_Collections_Casting - Fatal编程技术网

Java 在这段代码中有没有避免@SuppressWarnings的方法?

Java 在这段代码中有没有避免@SuppressWarnings的方法?,java,arrays,generics,collections,casting,Java,Arrays,Generics,Collections,Casting,是否有办法避免使用下面的@SuppressWarnings,并在没有警告“类型安全:未选中从AbstractDO[]到E[]的强制转换”的情况下保持相同的功能: 公共MyClass{ ... private Map您有一个选择:要么为您知道将始终成功的强制转换抑制警告,要么避免警告并使用try/catch块验证强制转换是否成功 只有这两种选择 也许有一种方法可以增强地图声明 对你来说,我认为你有几个选择 我认为最好的办法是在getConcreteDOs方法中添加throws-ClassCastE

是否有办法避免使用下面的
@SuppressWarnings
,并在没有警告“类型安全:未选中从AbstractDO[]到E[]的强制转换”的情况下保持相同的功能:

公共MyClass{
...

private Map您有一个选择:要么为您知道将始终成功的强制转换抑制警告,要么避免警告并使用try/catch块验证强制转换是否成功

只有这两种选择


也许有一种方法可以增强地图声明

对你来说,我认为你有几个选择

我认为最好的办法是在
getConcreteDOs
方法中添加
throws-ClassCastException
子句,让调用方处理由于无效使用该方法而导致的无效强制转换——假设他们可以让它围绕
extends-AbstractDO
子句编译。这有一个不幸的副作用,即使使用者将调用包装在try/catch块中,或声明他们自己的throws子句以强制try/catch块位于堆栈的更高位置

您可以用一个空的catch块来吞下异常;坦白说,我更喜欢@SuppressWarning而不是它

或者,您可以完全放弃该方法,只处理抽象实体,从而有效地让存储库的使用者处理转换


一句话:每当您尝试构建泛型存储库时,都会遇到这些问题。您最好使用每个实体类型的具体存储库模式。

您可以通过将类设置为泛型来避免未选中的强制转换,例如

public class MyClass<E extends AbstractDO> {

    private Map<Class<? extends AbstractDO>, E[]> map;

    public void saveConcreteDOs(E[] theEntities) {        
      map.put(theEntities[0].getClass(), theEntities);
    }

    public E[] getConcreteDOs(Class<E> theType) {
      return map.get(theType);
    }
}
公共类MyClass{

私有映射首先,您的代码不是类型安全的。它可能在运行时引发类强制转换异常。您应该

private void saveConcreteDOs(AbstractDO[] theEntities) { entityMap.put(theEntities.getClass().getComponentType(), theEntities); } 这没有警告,但有点作弊。
Class.cast()
为我们隐藏了警告,仅此而已

它对数组版本没有帮助,在
Class
中没有
t[]castArray(Object[])
。您可以自己创建一个方法,有效地将警告隐藏在其中

或者你可以这样做,但这确实是不必要的俗气。如果你知道你在做什么,并且仔细检查了你的程序以确保类型安全,不要害怕未经检查的强制类型转换警告

protected <E extends AbstractDO> E[] getConcreteDOs(Class<E[]> arrayType) 
{
  AbstractDO[] array = map.get(arrayType.getComponentType());
  return arrayType.cast(array);
}
...
X[] array = getConcreteDOs(X[].class);
protectede[]getConcreteDOs(类arrayType)
{
AbstractDO[]array=map.get(arrayType.getComponentType());
返回arrayType.cast(数组);
}
...
X[]数组=getConcreteDOs(X[].class);

以防万一,请忽略NPE和类似的错误-代码是缩写版本,当然,rays和泛型不能很好地混合,最好使用List。你能把
MyClass
变成generic吗?@starblue。更改为List不会删除警告,因为OP需要转换为
List
。但是List更可取,因为你可以重新设置urn
unmodifiableList
。是的,这只是一个一般性的评论。我认为grigory所做的是最佳实践,用一个单独的方法隔离强制转换,并应用
@SuppressWarnings(“未选中”)
仅针对该方法。也许有一种方法可以增强映射声明?请告诉我;我想说的是,无论何时从父对象强制转换到子对象,您都会收到此警告,因为编译器无法保证类型兼容。您的意思是“@SuppressWarnings”注释会影响运行时行为吗?(无论是否“铸造成功”)我理解得对吗?现在,这是一条新闻。@Nikita Rybak:不,@SuppressWarnings不会影响运行时行为。它用于那些通常担心编译器警告的人,但是他们知道,在这种情况下,警告是没有根据的,因为编译器无法理解某些东西。你应该只抑制这样的警告如果您知道警告无效,则发出警告。如果强制转换有很小的失败机会,则应使用try/catch块验证强制转换是否成功,或声明可能会出现无效强制转换异常(例如,使用Java中的throws子句,或使用C#中的文档)。您错了。例如,
T cast(对象o){return(T)o;}
在运行时并不真正执行任何操作。它不会在该位置抛出ClassCastException。当调用方尝试将返回的对象用作
T
时,会发生异常。如果调用方忽略返回值,则不会出现异常。我认为其目的是返回一个X[]当我以X.class作为参数调用它时,映射将包含每个类和相应数组的一个条目。你的建议意味着强制所有数组子类E..@grigory,那么你不能不进行未检查的强制转换。我同意避免警告和
@supersWarnings
本身不是目标。目标是有明确的,足够且自我解释的代码。这就是为什么我喜欢你的“如果你知道你在做什么,并且仔细检查了你的程序以确保类型安全,那么不要害怕未检查的强制转换警告。”关于类型安全的第一条注释我不清楚。怎么可能
实体[0]。getClass()
不能强制转换为
Class@grigory假设B是A的子类,如果
array=newa[]{new B(),new A()}
,则代码会认为该数组是A
B[]
我明白你的意思。但是我的代码没有对数组的类型做任何假设,只是对它的第一个元素做假设。我很感激你的回答,因为它到目前为止最有帮助。当我尝试这样做时:
map.put(theEntities.getClass().getComponentType(),theEntities);
我得到编译错误:方法put(Class,E[])
private Map<Class<? extends AbstractDO>, AbstractDO> map;

protected <E extends AbstractDO> E getConcreteDOs(Class<E> theType) 
{
  AbstractDO obj = map.get(theType);
  return theType.cast(obj);
}
protected <E extends AbstractDO> E[] getConcreteDOs(Class<E[]> arrayType) 
{
  AbstractDO[] array = map.get(arrayType.getComponentType());
  return arrayType.cast(array);
}
...
X[] array = getConcreteDOs(X[].class);