我目前正在使用play2框架.
我有几个类正在抛出exceptions但是play2s全局onError处理程序使用throwable而不是异常.
例如,我的一个班级正在抛出一个NoSessionException.如果它是一个可抛物体,我可以检查NoSessionException吗?
class Bouncy<T> extends Throwable {
}
// Error: the generic class Bouncy<T> may not subclass java.lang.Throwable
Run Code Online (Sandbox Code Playgroud)
为什么Java不支持泛型Throwable?
我意识到类型擦除使某些事情变得复杂,但显然Java已经经历了很多,所以为什么不再推动它,并允许泛型Throwables,通过全面的编译时检查潜在的问题?
我觉得类型擦除论证相当薄弱.目前,我们做不到:
void process(List<String> list) {
}
void process(List<Integer> list) {
}
Run Code Online (Sandbox Code Playgroud)
当然,我们没有它.我不要求,我们应该能够做到catch Bouncy<T1>,并Bouncy<T2>在同一个try块,但是如果我们使用他们在严格的编译时可执行的规则不相交的上下文(这是相当多的仿制药的工作方式现在),你说对不对可行吗?
我创建了一个"生成器"接口(用于方法引用,分别用于单元测试的模拟):
@FunctionalInterface
public interface Factory<R, T, X extends Throwable> {
public R newInstanceFor(T t) throws X;
}
Run Code Online (Sandbox Code Playgroud)
我创建的那样,因为我的第一个用例实际上必须抛出一些检查WhateverException.
但是我的第二个用例没有投掷X.
我能想出的让编译器满意的最好方法是:
Factory<SomeResultClass, SomeParameterClass, RuntimeException> factory;
Run Code Online (Sandbox Code Playgroud)
这编译,并做我需要的,但仍然是丑陋的.有没有办法保留单个接口,但在声明特定实例时不提供X?
什么是C#相当于Java Throwable?
在Java中,调用异常类层次结构的根Throwable,而不是 Exception.该Throwable基类有两个派生类:
Exception:对于合理的应用程序可能想要捕获的条件.
Error:对于一个合理的程序不应该试图抓住的严重问题.
因此Throwable基类包含合理程序不应该尝试捕获的问题.
编译时错误:泛型类可能不是java.lang.Throwable的子类
public class TestGenericClass<E> extends Exception {
/*Above line will give compile error, the generic class TestGenericClass<E> may
not subclass java.lang.Throwable*/
public TestGenericClass(String msg) {
super(msg);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的编译时错误是出于以下§jls-8.1.2中给出的原因,并在此问题中进行了解释:
如果泛型类是Throwable(第11.1.1节)的直接或间接子类,则是编译时错误.
由于Java虚拟机的catch机制仅适用于非泛型类,因此需要此限制.
题:
如何限制子类java.lang.Throwable不是泛型类?
或者更通用的问题是,如何限制任何类的子类不能通用?
当我运行此代码时,应用程序以ClassNotFoundException退出:
//uncaught ClassNotFoundException
try
{
Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null);
table.put(clazz.getName(), clazz);
}
catch (NoClassDefFoundError e)
{
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译此代码时,编译器会抱怨ClassNotFoundException无法访问,因为它不会从try-catch语句的try-clause中抛出.
//Won't compile
try
{
Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null);
table.put(clazz.getName(), clazz);
}
catch (ClassNotFoundException e)
{
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,捕获的唯一throwable是NoClassDefFoundError.
//catches throwable of type java.lang.NoClassDefFoundError,
//with a java.lang.ClassNotFoundException as its cause
try
{
Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null);
table.put(clazz.getName(), clazz);
}
catch (Throwable e)
{
System.out.println(e.getClass().getName());
System.out.println(e.getCause().getClass().getName());
}
Run Code Online (Sandbox Code Playgroud)
下面的代码将编译并捕获错误(并且只有错误),但它很笨拙:
//possible workaround
try
{
Class<?> …Run Code Online (Sandbox Code Playgroud) 我找不到Java 之间NoSuchMethodException和NoSuchMethodErrorJava 之间的确切区别.有人能给出解释和这两件事的例子吗?
多年来一直在做Java,所以一直没有跟踪C++.已经最后条款中增加了C++异常处理的语言定义是什么?
是否有一种模仿Java的尝试/终极的青睐成语?
我还担心C++没有可能抛出的所有可能异常的最终超类型 - 比如Java的Throwable类.
我可以写:
try {
// do something
} catch(...) {
// alas, can't examine the exception
// can only do cleanup code and perhaps rethrow, ala:
throw;
}
Run Code Online (Sandbox Code Playgroud)
附录编辑:
我最终接受了得票最多的答案,即使用析构函数进行清理.当然,从我自己的评论来看,很明显我并不完全同意这一点.但是,C++就是这样,所以在我想到的应用程序中,我会或多或少地努力坚持共同的社区实践.我将使用模板类来包装尚未具有类析构函数的资源(即C库资源),从而赋予它们析构函数语义.
新的附加编辑:
嗯,而不是最后一个封闭功能或许?结合ScopeGuard方法的闭包(参见下面的答案之一)将是一种通过任意操作完成清理并访问清理代码的外部范围上下文的方法.清理可以用在Ruby编程中看到的成语方式来完成,它们在打开资源时提供清理块.C++不考虑关闭功能吗?
我正在使用gradle作为JavaFX插件.即使在建立和运行分发之后的所有内容之后,一切都运行良好,除了一个类:CloseableHttpClient
出于几个目的,我创建了以下对象:
CloseableHttpClient client = HttpClients.createDefault();
Run Code Online (Sandbox Code Playgroud)
在IDE中运行程序没问题,一切正常.但是如果我构建并尝试运行.exe-File,我会得到以下Throwable-StackTrace:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.http.conn.ssl.SSLConnectionSocketFactory
at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:955)
at org.apache.http.impl.client.HttpClients.createDefault(HttpClients.java:58)
at ch.itcb.tools.lom.util.JsonSimpleUtil.http(JsonSimpleUtil.java:29)...
Run Code Online (Sandbox Code Playgroud)
我真的不明白.怎么可能只是这个班级找不到,但我所有的其他班级呢?
我的build.gradle文件:
apply plugin: 'java'
apply plugin: 'eclipse'
apply from: 'javafx.plugin'
sourceCompatibility = 1.8
version = '0.1'
jar {
manifest {
attributes 'Implementation-Title': 'LogoffManager',
'Implementation-Version': version
}
}
repositories {
mavenCentral()
}
dependencies {
compile fileTree(dir: 'lib', include: ['*.jar'])
compile 'ch.qos.logback:logback-classic:1.1.3'
compile 'org.apache.httpcomponents:httpclient:4.5.1'
compile 'com.googlecode.json-simple:json-simple:1.1'
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: …Run Code Online (Sandbox Code Playgroud) 有时,您只需要捕获Throwable,例如在编写调度程序队列时调度通用项目并需要从任何错误中恢复(所述调度程序记录所有捕获的异常,但是静默,然后继续执行其他项目).
我能想到的一个最佳实践是,如果它是InterruptedException,则总是重新抛出异常,因为这意味着有人打断了我的线程并想要杀死它.
另一个建议(来自评论,而不是答案)是始终重新抛出ThreadDeath
还有其他最佳做法吗?