泛型方法真的能够区分返回类型吗?

时间:2018-09-11 14:58:33

标签: java

在一些旧代码中,我发现了以下方法:

@foreach($items as $key => $item)

<!-- display category and button -->
<h3 class="uk-width-4-10">{{$item->category}}</h3>
<a href="#edit-modal{{ $key }}" data-uk-modal><span onclick="editCommentModal({{ $key }})" class="uk-icon-plus-square"></span></a>


<!-- modal -->
<div id="edit-modal{{ $key }}" class="uk-modal edit-modal">

<h3 class="uk-width-4-10">{{$item->category}}</h3>
<input type="hidden" name="edit_category[]" id="{{ 'edit_category_' . $item->id }}" value="{{$item->category}}" />

</div>

@endforeach


function editCommentModal(id){
 var inps = document.getElementsByName('edit_category[]');
 for (var i = 0; i <inps.length; i++) {
    var inp=inps[i];
    if('edit_category_' + id == inp.id)
    {
      console.log("edit_category["+i+"].value="+inp.value);
    }
 }
}    

这用于仅根据返回类型将任意对象转换为任何类型,

public static <T> T cast(Object o) {return (T) o;}

该强制转换方法如何能够转换为正确的类型?

2 个答案:

答案 0 :(得分:4)

不是

这是未经检查的强制类型转换,如果您要强制类型转换为不对齐的类型,将在运行时失败。

作为一个简单的案例,观察当我们尝试使用此方法将Integer列表转换为BigInteger列表时会发生什么情况。

List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5);

List<BigInteger> bigIntList = cast(intList);

for(BigInteger i : bigIntList) {
    System.out.println(i.doubleValue());
}

或者,对于一个较不那么人为却仍然损坏的演员表,尝试在整个演员表之间投射简单的类型。

Integer i = 10;
BigInteger bigI = cast(i);

System.out.println(bigI.doubleValue());

此旧代码已被危险地破坏,不应以任何形式进行转换。实际上,所需的转换类型应通过转换方法而非处理。

我应该注意-强制转换是您告诉Java编译器您不仅知道自己在做什么,而且还承担了失败的风险,这就是为什么编译器不会警告您的原因之一无效的类型。如果使用泛型正确完成了此操作(并且我不完全相信使用泛型有可能),那么您将收到一个编译时警告,指出您做错了什么。

答案 1 :(得分:4)

该方法不执行任何操作。实际的转换发生在作业上。

这是您如何查看发生的情况:

public static <T> T cast(Object o) {
    try {
        return (T) o;
    } catch (ClassCastException cce) {
        // This never gets printed
        System.out.println("Cast has failed");
        throw cce;
    } finally {
        System.out.println("Cast succeeded");
    }
}

现在使用会导致转换抛出的参数来调用该方法:

List<SomeType> foo = cast(new Integer(5));

您将看到“发布成功”的输出,然后将ClassCastException抛出进行调用的方法(demo)内。

此行为的原因是Java使用类型擦除来实现泛型。如果您想以一种在方法内部失败的方式来实现强制转换,请将Class<T>作为附加参数传递:

public static <T> T cast(Object o, Class<T> cls) {
    return cls.cast(o);
}