我想将Java中的接口方法记录为不允许传播异常,并进行某种静态分析,验证此方法的实现是否捕获并处理可能传播给它的任何异常。类似@NoThrow
。
例如,我希望能够写下:
interface SomeServiceProviderInterface {
@NoThrow
@NonNull
SomeResult someComputation();
}
...并且保证实现服从此接口契约。是否有注释和静态分析工具已经这样做了?如果没有,有没有人知道这是否可以通过注释处理器实现(它能看出代码是否包含try ... catch块?)和/或有关于如何实现这样的事情的任何指针或建议?谢谢!
答案 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现在正在做些什么,其中异常是部分异步处理的。