简体   繁体   English

为什么我不能在java中抛出或捕获泛型类的实例?

[英]Why can't I Throw or Catch Instances of a Generic Class in java?

I know that I can't throw or catch instances of generic class in Java,for example ,the following code compiles wrongly: 我知道我不能在Java中抛出或捕获泛型类的实例,例如,下面的代码编译错误:

public static <T extends Throwable> void test(Class<T> t){
    try{
        //do work
    }
    catch (T e){// ERROR--can't catch type variable
    Logger.global.info(...)
    }
}

Would anyone can explain the exactly reason for Java to forbidden throw or catch instances of generic class? 有人能解释Java禁止抛出或捕获泛型类实例的确切原因吗?

You can't catch a generic exception, because the Java Language Specification explicitly forbids it. 您无法捕获一般异常,因为Java语言规范明确禁止它。 In 14.20 The try statement it says: 14.20的try语句中它说:

It is a compile-time error if a type variable is used in the denotation of the type of an exception parameter. 如果在异常参数类型的表示中使用类型变量,则为编译时错误。

The section does not explain why, but the most like reason is that <T extends Throwable> is erased to Throwable , so your code would actually be compiled as if it was: 该部分没有解释原因,但最明显的原因是<T extends Throwable>被删除为Throwable ,因此您的代码实际上将被编译为如下:

public static void test(Class<? extends Throwable> t){
    try{
        //do work
    }
    catch (Throwable e){
    Logger.global.info(...)
    }
}

This is not the intent expressed by your code (and very likely not what you want), therefor the language specification explicitly forbids it. 这不是您的代码表达的意图(很可能不是您想要的),因此语言规范明确禁止它。

Note that throwing generic exceptions is allowed, but this is usually only relevant in the context of having some wrapper around another method that throws the exception. 请注意,允许抛出泛型异常,但这通常仅在使用另一个抛出异常的方法的包装器的上下文中相关。

You can not do this because the 'generic type erasure'. 你不能这样做,因为'泛型类型擦除'。 The generic information is lost after the compile time, after generate the bytecode class file there are not any generic information and at compile time you have not specified the concrete type for generic T. 通用信息在编译时丢失,生成字节码类文件后没有任何通用信息,在编译时你没有指定通用T的具体类型。

See this code for type erasure check, the result is Equal: 请参阅此代码以进行类型擦除检查,结果为Equal:

A 一种

package a;


public class A {

    public static void main(String[] args) {

        final B<String, Integer> b = new B<String, Integer>();

        b.check();
    }

}

B

package a;

import java.util.ArrayList;
import java.util.List;

public class B<T, E> {

    public void check(){

        final List<T> listT = new ArrayList<T>();
        final List<E> listE = new ArrayList<E>();

        if (listT.getClass().equals(listE.getClass())) {
            System.out.println("Equal");
        }
    }

}

See this link too: http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCatch 也可以看到这个链接: http//docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCatch

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能使用泛型类型的实例,但是不能在外部使用呢? - Why can't I use instances of a generic type but can outside? 为什么Java Generic无法设计继承到父Generic类? - Why Java Generic can't design to inherit to a parent Generic class? 为什么我不能在方法中抛出异常(Java) - Why Can't I Throw Exception In A Method(Java) Java:为什么我不能在Comparator中抛出异常? - Java: why can't I throw an exception in Comparator? 为什么我不能在 try catch 语句中调用的方法中抛出异常(已检查)? - Why i can`t throw Exception(checked) in a method that is invoked in a try catch statement? 为什么这个泛型引用不能指向Java中的这个类似扩展类? - Why this generic reference can't point to this similar extended class in Java? 为什么我不能赶上java.net.SocketTimeoutException? - why i can't catch java.net.SocketTimeoutException? 为什么不能在Java中重用WebElement对象实例? - Why can't I reuse WebElement object instances in Java? 即使有catch(Exception e),我也无法抛出NoRouteToHostException - I can't throw NoRouteToHostException even with catch(Exception e) 我不能完全让我的通用类在Java中工作 - I can't quite get my generic class to work in Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM