【问题标题】:A==B vs B==A, What are the differences [closed]A==B vs B==A,有什么区别[关闭]
【发布时间】:2012-03-26 19:39:04
【问题描述】:

所以长话短说。一位教授在课堂上提出了这个问题作为讨论的开始。除了明显的

B = new SomeClass("B"); // But B can be null, can can be new SomeClass("A");
A = new SomeClass("A");
A==B

比较时会保证没有NPE,用B==A代替A==B的原因是什么?

其中 A 和 B 属于同一类型,这与语言无关。因此,您可以假设 Java 为 A.equals(B),或 C 或 C++ 等中的等效语法......

不,这不是家庭作业。

【问题讨论】:

  • 每个场景和语言都有非常不同的答案。
  • 使用==(假设它没有重载)不会抛出C#。
  • 为什么这会同时标记 Java 和 C#?在 Java 中,== 永远不会抛出 NEP。
  • 很多时候,如果 B 是常数,人们会做 B==A。这背后的想法是,捕捉您不小心在语句中放置一个“=”的情况,从而导致分配而不是检查。在某些语言中,运行的代码最终可能会有所不同,具体取决于您是否执行 A==B 或 B==A(想想 A 和 B 是两种不同的类型,它们都具有 == 运算符重载,或者是否通过 .Equals 实现, A 和 B 可能有不同的 .Equals()。
  • @NullUserException 可能与这个问题无关,但是当涉及自动装箱/拆箱时,Java == 可以抛出 NPE。

标签: c# java programming-languages


【解决方案1】:

在 Java 中,A == BB == A 始终具有相同的语义。在 C#(具有运算符重载)中,如果 BA 类的子类的实例,则可能会有所不同。

请注意,A.equals(B) 不等同于 A == B

【讨论】:

  • 我其实是在寻找更多的东西,但没有考虑到 C# == 有重载,但我会将子类示例进行测试。但这是我没有考虑过的。
  • @Churk - 相等性测试的危险之一(与测试身份相反)是子类可以对相等性有不同的想法,这很容易破坏交换性。没有什么好的办法。
【解决方案2】:

在 C# 中,运算符不能保证可交换,因为它们可以重载,因此 A == B 不一定会返回与 B == A 相同的结果。

例如

    class Program
    {
        static void Main(string[] args)
        {
        var a = new MyClass("A");
        var b = new MyClass("B");

        Console.WriteLine(a == b);
        Console.WriteLine(b == a);

        Console.ReadLine();
    }


    public class MyClass
    {

    private string _Name;

    public MyClass(string name)
    {
        if (_FirstInstance == null)
        {
            _FirstInstance = this;
        }
        this._Name = name;
    }

    private static MyClass _FirstInstance = null;

    public static bool operator ==(MyClass left, MyClass right)
    {
        return object.ReferenceEquals(left, _FirstInstance);
    }

    public static bool operator !=(MyClass left, MyClass right)
    {
        return !(left == right);
    }
}

是的,我知道这太疯狂了。

【讨论】:

    【解决方案3】:

    我想你的意思是.equals,而不是==。如果a 为空,a.equals(b) 将抛出 NPE,但如果 b 为空则不会。所以如果你知道a 不为空,你应该做a.equals(b) 而不是相反。

    不是,但是,与语言无关。有些语言根本没有 null!

    【讨论】:

    • 这是显而易见的原因之一,这就是 A 被初始化的原因。
    【解决方案4】:

    在 java 中,您可以执行 A == B 或 B == A,但您不会得到 NPE。真正的问题是当你这样做时

    String s = ...;
    boolean isNull = s.equals("myString");
    

    而不是

    boolean isNull = "myString".equals(s);
    

    由于您在对象上调用方法,并且“myString”是正确实例化的对象,因此无论变量“s”是否为空,第二次调用都不会抛出 NPE。第一次调用时您不会得到保证,因为您不确定“s”赋值右侧的“...”是“yourString”还是 null。

    【讨论】:

    • 这是确保没有 NPE 的明显原因之一,但我正在寻找其他原因。我和很多人谈不上,教授没有说出来。所以我很好奇有没有。
    • 即使在您编辑的示例中,也没有 NPE 的风险,因为您没有在可能的空引用上调用方法,您只是在比较两个引用以查看它们是否是相同的。在 Java 中,排序与“==”无关。
    【解决方案5】:

    在 Java 中

    Object a = new Object();
    Object b = null;
    System.out.println(a.equals(b));  //false
    System.out.println(b.equals(a));  //NPE!
    

    所以如果你有一个已知的常数值,它应该在表达式的左边。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-27
      • 2012-07-03
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 1970-01-01
      • 2017-04-06
      • 2020-10-09
      相关资源
      最近更新 更多