如何避免“未使用的参数” 重写 java 1.4 中的方法时出现警告?
在此代码中:
public class MyClass {
private Object innerValue;
public Object getInnerValue() {
return this.innerValue;
}
public void setInnerValue(Object innerValue) {
this.innerValue = innerValue;
}
}
public class MyClassReadOnly extends MyClass {
MyClassReadOnly(MyClass cls) {
// Make a field by field copy
super.setInnerValue(cls.getInnerValue());
}
public void setInnerValue(Object innerValue) {
throw new UnsupportedOperationException(
"This is a read-only instance"
);
}
}
编译器正确地抱怨 MyClassReadOnly.setInnerValue() 中未使用的参数(从未读取)innerValue。
我不想禁用这种警告,因为它通常非常有用,而且我不想有任何警告来获得高信噪比。
我不能使用 @SuppressWarnings() 构造作为建议的另一个问题,因为它只是 Java 1.4。
我想过像这样插入虚拟代码,但它不是很令人满意:
public void setInnerValue(Object innerValue) {
if (innerValue != null) { /* Do Nothing, but keep the compiler happy */ }
throw new UnsupportedOperationException("This is a read-only instance");
}
In this code :
public class MyClass {
private Object innerValue;
public Object getInnerValue() {
return this.innerValue;
}
public void setInnerValue(Object innerValue) {
this.innerValue = innerValue;
}
}
public class MyClassReadOnly extends MyClass {
MyClassReadOnly(MyClass cls) {
// Make a field by field copy
super.setInnerValue(cls.getInnerValue());
}
public void setInnerValue(Object innerValue) {
throw new UnsupportedOperationException(
"This is a read-only instance"
);
}
}
The compiler complains rightly about the unused parameter(never read) innerValue in MyClassReadOnly.setInnerValue().
I don't want to disable this kind of warnings since it's quite useful usually, and I don't want to have any warnings either to have a high signal/noise ratio.
I cannot use the @SuppressWarnings() construct as another question suggested since it's Java 1.4 only.
I thought about inserting dummy code like this, but it's not very satisfactory :
public void setInnerValue(Object innerValue) {
if (innerValue != null) { /* Do Nothing, but keep the compiler happy */ }
throw new UnsupportedOperationException("This is a read-only instance");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
警告不是问题,恐怕是设计的问题。
您当前的层次结构违反了里氏替换原则,因为接收 MyClass 实例的类期望 setInnerValue 正常工作,并且可能无法正确处理此异常。 你可以说一个可读写的X是一种可读-X,但你不能说一个可读-X是一种可读写的X。
当我面对这种情况时,我创建一个名为 IMyX 的读取接口,一个名为 IMutableMyX 的写入子接口,然后实际的类实现 IMutableMyX,从而也实现 IMyX。 然后,我非常小心,仅在需要时传递 IMutableMyX,并在所有其他情况下传递 IMyX。
我觉得使用编译器和类型来限制访问比依赖运行时异常更好。 它还使您的代码更加清晰,并强制您在需要写访问时显式向下转换接口。
我意识到这并不能回答您关于消除警告的问题。 但警告可以被抑制、忽略或解决。 未使用的参数通常是一种不好的味道,表明您的方法可能没有执行预期的操作。 方法应该只获取必要的参数。 如果不使用该参数,则该参数不是必需的,因此需要进行更改。
The warning is not the problem, I'm afraid that the design is.
Your current hierarchy violates Liskov's principle of substitution since a class receiving an instance of a MyClass expects setInnerValue to work, and may not handle this exception correctly. You can say that a read-and-write X is a type of readable-X, but you cannot say that a readable-X is a type of read-and-writable X.
When I am faced with this sort of situation, I create an interface called IMyX with the reads, a subinterface called IMutableMyX with the writes, and then the actual class implements IMutableMyX and thus also IMyX. I am then very careful to only pass IMutableMyX when I need to, and pass IMyX in all other cases.
I feel that it is better to use the compiler and types to restrict access than it is to count on runtime exceptions. It also makes your code a lot clearer, and forces you to explicitly downcast the interface when you do want write-access.
I realize this does not answer your question about getting rid of the warnings. But warnings can either be suppressed, ignored, or addressed. An unused parameter is often a bad smell that indicates your method might not be doing what it's expected to do. Methods should only get essential parameters. If the parameter is not used, the parameter is not essential, and therefore something needs to be changed.
恐怕您被虚拟代码困住了。 在 C/C++ 中,您可以使用宏 (
#define _unused(x) ((void) x)
),但(void) variable;
不是有效的Java 中的声明。如果这让您感觉好一些,编译器可能会优化掉空的 if 块。
I'm afraid you're stuck with dummy code. In C/C++, you could use a macro (
#define _unused(x) ((void) x)
), but(void) variable;
isn't a valid statement in Java.If it makes you feel better, the compiler will likely optimize away the empty if-block.
您可以安全地输入以下行:
innerValue = null
;位于函数顶部所有未使用的参数。
它不会影响调用者,但会让编译器满意。
You can safely enter lines like:
innerValue = null
;at the top of the function for all unused args.
It will not affect the caller, but will keep the compiler happy.
我不会玩任何“代码技巧”只是为了让编译器警告消失,希望编译器优化这些技巧。 事实上,这个编译器警告有那么有用吗? 我只会禁用它。 使用 Java 5 后,您可以使用
@SuppressWarnings
并重新启用它。IMO,仅仅因为它们存在就启用所有可能的警告,然后着手让每个警告消失,这是一个坏主意。 找出哪些警告对您的环境真正有意义并禁用其余警告。
I wouldn't play any "code tricks" just to make a compiler warning go away, hoping for the compiler to optimize away the tricks. In fact, is this compiler warning all that useful? I would just disable it. Once you are using Java 5, you can use
@SuppressWarnings
and reenable it.IMO, it's a bad idea to enable all possible warnings, just because they exist, and then set out to make every single warning go away. Figure out which warnings actually make sense for your environment and disable the rest.
如果您使用的是 Eclipse(?),您可以打开 Parameter Is Never Read 警告,但忽略覆盖和实现方法中的情况(这将解决此特定问题),以及单独使用“@param”标记记录的情况(尽管这当然不适用于 Java 1.4)。 我希望大多数其他 Java IDE 也能提供类似的设置。
If you're using Eclipse (?), you can turn on Parameter Is Never Read warnings, but ignore cases in overriding and implementing methods (which would solve this specific problem) and, separately, those documented with the "@param" tag (although of course that doesn't apply to Java 1.4). I would expect most other Java IDEs to have similar settings available.