我有一些关于在Java中处理异常的问题.我读了一下它并得到了一些矛盾的指导方针.
我们来看看上面提到的文章:
它声明如果"客户端代码无法执行任何操作",通常应避免使用已检查的异常.但它究竟意味着什么?在GUI中显示错误消息是否有足够的理由冒泡检查异常?但它会迫使GUI程序员记住捕获RuntimeExceptions及其后代以显示潜在的错误信息.
本文中提出的第二个观点是,除非我想在其中实现一些关税字段/方法,否则应该避免发明自己的异常类.我通常不同意这一点,我今天的练习恰恰相反:我将自己的异常结构中的异常包装到我编写的类实现的反射目标中,即使它们只是在不添加任何新方法的情况下扩展Exception.我认为在抛出更高层时更灵活地处理它们对于将使用这些类的程序员来说通常更清晰和易于理解.
我今天实现了一些代码,在文章中抛出RuntimeException,然后我让Sonar分析它.为了让我更加困惑,Sonar将我的RuntimeExceptions标记为主要错误,并标记为"避免在自己的类型中抛出root类型异常,wrap'em".
所以它看起来很有争议,你怎么看?
我今天也从一位技术主管那里听说,只是包装异常是不好的,因为这对JVM来说是一个非常昂贵的操作.对我来说,另一方面,在任何地方抛出SQLExceptions或IOExceptions看起来有点破坏封装.
那么你对我在这里提出的问题的一般态度是什么?
何时在我自己的类型中包装异常,何时不应该这样做?
哪里的那点客户端"不能做任何有关这一点,抛出运行时异常?"
性能问题怎么样?
更新:我找到了答案,如果没有其他人的话,我会在几天后发布.
我正在创建一个数字结构,所以我正在重载算术运算符.以下是表示4位无符号整数的结构的示例:
public struct UInt4
{
private readonly byte _value;
private const byte MinValue = 0;
private const byte MaxValue = 15;
public UInt4(int value)
{
if (value < MinValue || value > MaxValue)
throw new ArgumentOutOfRangeException("value");
_value = (byte) value;
}
public static UInt4 operator +(UInt4 a, UInt4 b)
{
return new UInt4((a._value + b._value) & MaxValue);
}
}
Run Code Online (Sandbox Code Playgroud)
重载加法运算符允许此代码:
var x = new UInt4(10);
var y = new UInt4(11);
var z = x + y;
Run Code Online (Sandbox Code Playgroud)
这里,计算溢出,因此变量z具有该值5 …
我有一些这种结构的代码:
public void method() {
Object o;
try {
o = new Object();
} catch (Exception e) {
//Processing, several lines
throw new Error(); //Our own unchecked exception
}
doSomething(o);
}
Run Code Online (Sandbox Code Playgroud)
我有很多方法,我在catch块中有相同的代码,所以我想将它提取到一个方法,以便我可以保存一些行.我的问题是,如果我这样做,我得到编译器错误"局部变量o可能没有被初始化".
public void method() {
Object o;
try {
o = new Object();
} catch (Exception e) {
handleError();
}
//doSomething(o); compiler error
}
private void handleError() throws Error {
//Processing, several lines
throw new Error();
}
Run Code Online (Sandbox Code Playgroud)
有没有解决方法?
我一直在阅读关于未经检查和已检查的问题,没有一个在线资源真正清楚这些差异以及何时使用两者.
根据我的理解,它们都会在运行时抛出,它们都代表超出逻辑预期范围的程序状态,但必须明确捕获已检查的异常,而未经检查的异常则不会.
我的问题是,假设为了论证我有一个方法来划分两个数字
double divide(double numerator, double denominator)
{ return numerator / denominator; }
Run Code Online (Sandbox Code Playgroud)
以及需要在某处使用divison的方法
void foo()
{ double a = divide(b, c); }
Run Code Online (Sandbox Code Playgroud)
谁负责检查分母为零的情况,是否应该检查或取消检查异常(忽略Java内置的分区检查)?
那么,除法方法是按原样还是按原样声明
double divide(double numerator, double denominator) throws DivideByZeroException
{
if(denominator == 0) throw DivideByZeroException
else ...
}
void foo()
{
try{
double a = divide(b, c);
}
catch(DivideByZeroException e)
{}
}
Run Code Online (Sandbox Code Playgroud)
或者没有经过检查的例外,原样如下:
double divide(double numerator, double denominator)
{
if(denominator == 0) throw DivideByZeroException
else ...
}
void foo()
{
if(c != 0)
double a = …Run Code Online (Sandbox Code Playgroud) PowerShell 似乎在算术运算和转换后执行边界检查。例如,以下操作失败:
[byte]$a = 255
$a++
$a = [byte]256
Run Code Online (Sandbox Code Playgroud)
有没有办法强制溢出或类型转换,而无需通过模或 C# 和 Add-Type 进行手动计算?
在我目前正在从事的项目中,我遇到了一些与Dagger 2相关的未经检查的警告。
为了排除与项目相关的因素,我尝试编译GitHub上提供的Dagger 2示例,它们还会引起这些未经检查的警告。见下文。
/MY_DIRECTORY/../DaggerApplicationComponent.java:28:警告:[未选中]未选中的转换
this.demoApplicationMembersInjector = DemoApplication_MembersInjector.create(((MembersInjector)MembersInjectors.noOp(),ProvideLocationManagerProvider);
必需:MembersInjector
<Application>找到:成员喷射器
显然,create方法需要使用MembersInjector,<Application>但是Dagger 2默认将传递的对象强制转换为MembersInjector。
我想修复这些问题,以使日志保持干净,并且buildserver再次编译项目。
我正在使用的一些设置:
我曾经使用过@SuppressWarnings("unchecked"):
class SomeClass {
public static void main(String [] args) {
Vector v = new Vector();
@SuppressWarnings("unchecked")
v.addElement(new Integer(1_000_000));
// ...
Run Code Online (Sandbox Code Playgroud)
在使用 javac 8.0 版进行编译时,出现以下错误:
error: <identifier> expected
v.addElement(new Integer(1_000_000));
Run Code Online (Sandbox Code Playgroud)
插入符号 (^) 指向addElement方法的左括号,还有一条错误消息抱怨缺少分号 (;)。第二条消息在 的右括号附近显示了插入符号addElement。
但是,当我将@SuppressWarnings("unchecked")上面的class SomeClass{, 线移动时,如下所示:
@SuppressWarnings("unchecked")
class SomeClass {
Run Code Online (Sandbox Code Playgroud)
两个错误消息都会自动消失。这让我不知所措。定位有@SuppressWarnings("unchecked")那么关键吗?
如果我将 Int32.MinValue 和 -1 传递到Divide()方法中,System.OverflowException尽管块发生在unchecked块中,我还是得到 a 。
private static int Divide(int n, int d)
{
return unchecked (n / d);
}
Run Code Online (Sandbox Code Playgroud)
这让我感到惊讶 - 除非我错误地阅读了已检查/未检查的文档,否则我希望它只会给我一个溢出的输出(因为 Int32.MinValue / -1 = 2^31 = Int32.MaxValue + 1,我期待溢出到 Int32.MinValue 的值)。相反,它抛出了一个OverflowException.
这是一个显示问题的DotNetFiddle。
Intellij 向我发出以下警告。不确定如何解决它,或者即使我需要解决它。警告详细信息说它仅适用于 JDK 5,而我使用的是 6。我想知道是否需要对此做出回应,如果需要,如何回应?
方法调用导致警告
List<T> refObject = cache.getCachedRefObject(cacheKey, List.class);
Run Code Online (Sandbox Code Playgroud)
被调用的方法
public <T> T getCachedRefObject(String objectKey, Class<T> type) {
return type.cast(refObjectCache.get(objectKey));
}
Run Code Online (Sandbox Code Playgroud)
警告详情
Unchecked Assignment
JDK 5.0 only. Signals places where an unchecked warning is issued by the compiler, for example:
void f(HashMap map) {
map.put("key", "value");
}
Run Code Online (Sandbox Code Playgroud) 如何在保持公共接口的同时进一步提高以下代码的性能:
public interface IMapper<in TSource, in TDestination>
{
void Map(TSource source, TDestination destination);
}
public static TDestination Map<TSource, TDestination>(
this IMapper<TSource, TDestination> translator,
TSource source)
where TDestination : new()
{
var destination = new TDestination();
translator.Map(source, destination);
return destination;
}
public static List<TDestination> MapList<TSource, TDestination>(
this IMapper<TSource, TDestination> translator,
List<TSource> source)
where TDestination : new()
{
var destinationCollection = new List<TDestination>(source.Count);
foreach (var sourceItem in source)
{
var destinationItem = translator.Map(sourceItem);
destinationCollection.Add(destinationItem);
}
return destinationCollection;
}
Run Code Online (Sandbox Code Playgroud)
public class MapFrom …Run Code Online (Sandbox Code Playgroud) unchecked ×10
java ×6
c# ×3
exception ×3
checked ×2
performance ×2
.net ×1
allocation ×1
android ×1
dagger-2 ×1
generics ×1
lint ×1
powershell ×1
throw ×1