直接通用例外

时间:2015-06-04 12:20:26

标签: java exception generics

我的问题是这个问题的后续行动:

Why doesn't Java allow generic subclasses of Throwable?

这个问题得到了很好的回答,但仅限于间接一般例外,那就是:

static func makeRequest(url: String, callback: APICallback) {
  let urlObject = NSURL(string: url)
  var request = createRequest(urlObject!, method: "GET") // internal
  var session = NSURLSession.sharedSession()
  var task = session.dataTaskWithRequest(request, completionHandler: gotResponse)
  task.resume()
}


static private func gotResponse (nsdata: NSData!, response: NSURLResponse!, err: NSError!) -> Void {

  // Do my parsing and handling here, instead.
  // OOPS! Don't have access to the callback. :(
}

什么是空的,是直接泛型:

public class MyException<T> extends Exception {

为什么不允许这样做?

虽然,我认为这是不允许的唯一原因是,public static <T extends Exception> void checkForException(Class<T> exType) { try { // some code } catch (T e) { e.printStackTrace(); } } 可能是一种类型,也明确地被捕获:

T

但这是阻止它的好理由吗?  同样的效果也可以在没有泛型的情况下完成:

// if T is IOException
catch(T e) { }
catch(IOException e) { }

这是上述限制的documentation

2 个答案:

答案 0 :(得分:0)

如果我们的异常类型是通用的,我们在编译时不知道实际类型,并且在运行时,类型被擦除。 throw 这样的异常是可能的,因为Class<T>允许我们构造一个实例,但 catch ing 必须知道类型在编译时匹配。但是它无法知道类型,因为它没有在catch站点指定。

答案 1 :(得分:0)

因为在 not reifiable 中,在Java类型变量中,即 T Type Erasure

这意味着编译器在运行时根本没有 T

因此,你的捕获块无法知道 T 最初是什么。不,你不能把它当作基本类型。这会做一些完全不同的事情。怎么样?

catch(T e) { }
catch(MyBaseException e) { }
catch(MyApplicationException e) { }

T 扩展 MyBaseException 。看看它真的很快变坏了吗?

在精彩的Java Generics FAQs - Under The Hood Of The Compiler

中阅读更多内容

就我个人而言,我从不喜欢类型擦除,但语言设计师发誓他们有使用它的理由。我们在这里。