是否有任何标准注释来指示Java中的nothrow语义?

时间:2015-09-03 01:04:36

标签: java exception annotations

我想将Java中的接口方法记录为不允许传播异常,并进行某种静态分析,验证此方法的实现是否捕获并处理可能传播给它的任何异常。类似@NoThrow

的内容

例如,我希望能够写下:

interface SomeServiceProviderInterface {
   @NoThrow
   @NonNull
   SomeResult someComputation();
}

...并且保证实现服从此接口契约。是否有注释和静态分析工具已经这样做了?如果没有,有没有人知道这是否可以通过注释处理器实现(它能看出代码是否包含try ... catch块?)和/或有关于如何实现这样的事情的任何指针或建议?谢谢!

2 个答案:

答案 0 :(得分:1)

不能有这样的注释,因为无法保证方法不会引发异常。这是因为any method may throw a VirtualMachineError at anytime。特别是,即使方法本身不直接或间接分配内存(使用INFO:tensorflow:Calling model_fn. Traceback (most recent call last): File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\ops\array_ops.py", line 1811, in zeros tensor_shape.TensorShape(shape)) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\tensor_shape.py", line 690, in __init__ self._dims = [as_dimension(d) for d in dims_iter] File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\tensor_shape.py", line 690, in <listcomp> self._dims = [as_dimension(d) for d in dims_iter] File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\tensor_shape.py", line 632, in as_dimension return Dimension(value) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\tensor_shape.py", line 185, in __init__ self._value = int(value) TypeError: int() argument must be a string, a bytes-like object or a number, not 'Tensor' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "LSTM_TFdataset-distributed.py", line 323, in <module> main(a) File "LSTM_TFdataset-distributed.py", line 233, in main tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec) File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\training.py", line 471, in train_and_evaluate return executor.run() File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\training.py", line 638, in run getattr(self, task_to_run)() File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\training.py", line 643, in run_chief return self._start_distributed_training() File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\training.py", line 789, in _start_distributed_training saving_listeners=saving_listeners) File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\estimator.py", line 358, in train loss = self._train_model(input_fn, hooks, saving_listeners) File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\estimator.py", line 1124, in _train_model return self._train_model_default(input_fn, hooks, saving_listeners) File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\estimator.py", line 1154, in _train_model_default features, labels, model_fn_lib.ModeKeys.TRAIN, self.config) File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\estimator.py", line 1112, in _call_model_fn model_fn_results = self._model_fn(features=features, **kwargs) File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\keras.py", line 278, in model_fn labels) File "D:\Shahriar\Python36\lib\site-packages\tensorflow_estimator\python\estimator\keras.py", line 201, in _clone_and_build_model optimizer_iterations=global_step) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\models.py", line 466, in clone_and_build_model clone = clone_model(model, input_tensors=input_tensors) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\models.py", line 271, in clone_model return _clone_functional_model(model, input_tensors=input_tensors) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\models.py", line 161, in _clone_functional_model **kwargs)) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 701, in __call__ return super(RNN, self).__call__(inputs, **kwargs) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 554, in __call__ outputs = self.call(inputs, *args, **kwargs) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 2416, in call inputs, mask=mask, training=training, initial_state=initial_state) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 759, in call inputs, initial_state, constants) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 863, in _process_inputs initial_state = self.get_initial_state(inputs) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 679, in get_initial_state inputs=None, batch_size=batch_size, dtype=dtype) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 2194, in get_initial_state self, inputs, batch_size, dtype)) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 3001, in _generate_zero_filled_state_for_cell return _generate_zero_filled_state(batch_size, cell.state_size, dtype) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 3017, in _generate_zero_filled_state return nest.map_structure(create_zeros, state_size) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\util\nest.py", line 381, in map_structure structure[0], [func(*x) for x in entries]) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\util\nest.py", line 381, in <listcomp> structure[0], [func(*x) for x in entries]) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\keras\layers\recurrent.py", line 3014, in create_zeros return array_ops.zeros(init_state_size, dtype=dtype) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\ops\array_ops.py", line 1814, in zeros shape = ops.convert_to_tensor(shape, dtype=dtypes.int32) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 1039, in convert_to_tensor return convert_to_tensor_v2(value, dtype, preferred_dtype, name) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 1097, in convert_to_tensor_v2 as_ref=False) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 1175, in internal_convert_to_tensor ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\ops\array_ops.py", line 1102, in _autopacking_conversion_function return _autopacking_helper(v, dtype, name or "packed") File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\ops\array_ops.py", line 1054, in _autopacking_helper return gen_array_ops.pack(elems_as_tensors, name=scope) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\ops\gen_array_ops.py", line 6426, in pack "Pack", values=values, axis=axis, name=name) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\op_def_library.py", line 350, in _apply_op_helper g = ops._get_graph_from_inputs(_Flatten(keywords.values())) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 5713, in _get_graph_from_inputs _assert_same_graph(original_graph_element, graph_element) File "D:\Shahriar\Python36\lib\site-packages\tensorflow\python\framework\ops.py", line 5649, in _assert_same_graph original_item)) ValueError: Tensor("lstm/zeros/packed/1:0", shape=(), dtype=int32, device=/job:chief/task:0) must be from the same graph as Tensor("strided_slice:0", shape=(), dtype=int32). 运算符),方法也可能抛出OutOfMemoryError 。这不仅是理论上的问题:如果垃圾回收线程花费的时间太长,一些并发的垃圾回收器会这样做。

答案 1 :(得分:1)

答案不令人满意

异常是一种有价值的语言元素,也可以简化计算。您正在以高度分支的递归算法搜索最短列表的图像。找到空列表时,可以通过为找到的空列表抛出异常来立即返回结果。

当然,跳过子程序是跳过不可行的计算,而不是增加空值。

因此,此问题是在避免许多if语句以促进测试的水平上进行的(否则,未经测试的代码段可能会被埋在代码的控制流中)。

将花费很多精力进行类扫描以导入异常类和危险调用(Integer.parseInt)。其中一些代码分析器已经发出警告。

我认为try {...} catch (Throwable/RuntimeException e) {}仅适用于某些遗留情况。那里的AOP也有帮助。

最佳选择 是集成异常。有评估库(我不记得它的名称-可能与 continuations 相关)可以处理异常并处理混合结果。 Streams现在正在做些什么,其中异常是部分异步处理的。