关于比较不同类型的断言:多余且愚蠢?

huangapple go评论64阅读模式
英文:

Assertions about comparing different types: redundant and silly?

问题

The Java code you provided overrides the "equals" method for a class and checks if the objects are instances of the same class before making comparisons. Some tools suggest that this check may be redundant and unnecessary when comparing objects of different classes, like in your test case where you compare a "NumeroSeccion" object with a String.

However, whether this check is redundant or not depends on your specific requirements and design choices. If you want to ensure that objects are only compared when they are of the same class and consider it a valid use case, you can keep the class type check.

In some scenarios, such checks might indeed be considered unnecessary, and you can choose to omit them if you're confident that your code logic ensures objects of different classes won't be compared.

Ultimately, it's a design decision, and these tools provide suggestions, but you should evaluate them in the context of your project's requirements and coding standards.

英文:

So I have this Java code that overrides equals for a class:

@Override public boolean equals(Object o) {
	if (o instanceof NumeroSeccion) {
		NumeroSeccion numSec = (NumeroSeccion) o;
		return Arrays.equals(this.valor, numSec.valor);
	} else {
		return false;
	}
}

which basically follows the common rule about checking if both objects are of the same class before doing anything else. Others prefer using getClass(), but the idea is the same.

Now I wrote some tests for it, including:

void notEqualsOtherClass() {
    NumeroSeccion ns1 = new NumeroSeccion("1.2.3.4.5");
    String ns2Str = "1.2.3.4.5";
    assertNotEquals(ns1, ns2Str);
}

According to IntelliJ IDEA, this is "possibly redundant":

> Possibly redundant assertion: incompatible types are compared 'NumeroSeccion' and 'String'

According to Sonar static code analysis, this is a "silly equality check":

> Silly equality checks should not be made. Comparisons of dissimilar types will always return false. The comparison and all its dependent code can simply be removed. This includes: comparing unrelated classes.

Is it actually redundant checking class types or add a test for this check, or are all these tools giving bad advice?

答案1

得分: 4

警告所给的建议适用于生产代码。测试代码是一种特殊情况,您是故意做一些错误的事情以测试某些东西。因此,警告是完全合理的,但恰巧在测试代码中不适用。

您可以安全地仅在测试代码的特定行中抑制该警告***。

或者,您可以使用一个技巧来欺骗编译器(和/或IDE),以便不发出警告。例如,您可以使用Object ns2Str = "1.2.3.4.5";而不是String ns2Str = "1.2.3.4.5";。这可能会消除警告。

英文:

The advice given by the warning is valid for production code. Testing code is a special case, where you are deliberately doing something wrong in order to test something. So, the warning is perfectly legitimate, but it just so happens to be inapplicable in testing code.

You can safely suppress the warning in that specific line of test code only.

Alternatively, instead of suppressing the warning you can use a trick to fool the compiler (and/or the IDE) so that the warning is not issued. For example, instead of String ns2Str = "1.2.3.4.5"; you may do Object ns2Str = "1.2.3.4.5"; This will probably get rid of the warning.

答案2

得分: 1

First, in your implementation of Object::equals, the use of instanceof and the comparison of Object::getClass for this and other are not equivalent!

public class Parent {}
public class Child extends Parent {}

final var v1 = new Parent();
final var v2 = new Child();

final var check1 = v2 instanceof Parent; // is true
final var check2 = v2.getClass().equals( v1.getClass() ); // is false
final var check2 = v2.getClass().equals( Parent.class ); // is false

For the implementation of equals(), this makes a significant difference. Usually, you should use instanceof in the implementation of equals() only for final classes.


The warnings you got from your tools are because these know the result of the comparisons already before the execution of your program, and therefore they assume that the respective code is at least obsolete, if not wrong. The tools did not look into your implementation of equals(), but they assume a proper implementation, so they also assume that an instance of NumeroSeccion could never be equal to an instance of String.

英文:

First, in your implementation of Object::equals, the use of instanceof and the comparison of Object::getClass for this and other are not equivalent!

public class Parent {}
public class Child extends Parent {}

final var v1 = new Parent();
final var v2 = new Child();

final var check1 = v2 instanceof Parent; // is true
final var check2 = v2.getClass().equals( v1.getClass() ); // is false
final var check2 = v2.getClass().equals( Parent.class ); // is false

For the implementation of equals(), this makes a significant difference. Usually, you should use instanceof in implementation of equals() only for final classes.


The warnings you got from your tools are because these know the result of the comparisons already before the execution of your program, and therefore they assume that the respective code is at least obsolete, if not wrong. The tools did not look into your implementation of equals(), but they assume a proper implementation, so they also assume that an instance of NumeroSeccion could never be equal to an instance of String.

huangapple
  • 本文由 发表于 2023年5月11日 16:16:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76225482.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定