0

就像问题所说的那样。理想情况下,答案应该是错误的,因为它将使用 Object#equal ,它只是参考比较。

    String cat = new String("cat");
    String cat2 = new String("cat"); 

    System.out.println(((Object) cat).equals((Object) cat2)); // returns true, but should be false

这与多态性有关。我知道如何equals()和实习工作。

相关主题:铸造图形 -> GRAPHICS2D

上述场景是向上转换的情况,其中String 被向下转换为 Object。

然而,一个常见的用法实际上是向下转换 GraphicsGraphics2D使用 Graphics 本身不存在的升级或新方法。为什么我们可以向上而不是向下。

import java.awt.*;
import javax.swing.*;

    public class Example extends JPanel {
        public static void main (String []args){
        JFrame frame = new JFrame();
    }
    public void paintComponent(Graphics g){
        Graphics2D g2 = (Graphics2D) g;             // How can we be sure the informal 
        g2.drawLine(0,0, getWidth(), getHeight());  // parameter contains those methods?
    }
}
4

5 回答 5

4

cat转换为,但这并没有改变它是一个实例Object的事实。Java 执行动态绑定(也称为后期绑定),这意味着方法调用在运行时根据对象是实例的类来解决。在这种情况下,那仍然是,这意味着将使用,而不是。你投到的事实几乎没有什么区别——无论如何都需要争论。catString StringString#equals() Object#equals()cat2Objectequals()Object

这是向自己证明这一点的简单方法:

String s = "abc";
Object o = (Object) s;  // we don't really need an explicit cast

System.out.println(s.getClass());
System.out.println(o.getClass());
类 java.lang.String
类 java.lang.String

同样的原理在这里起作用。ois 的类型Object,但它是一个String实例,因此String'sgetClass()被调用。


考虑以下类结构:

class A {
    public void foo() {
        System.out.println("A foo");
    }
}

class B extends A {
    public void foo() {
        System.out.println("B foo");
    }

    public void bar() {
        System.out.println("B bar");
    }
}

现在,当我们有类似的东西时

A b = new B();
b.foo();

thenBfoo方法将被调用。这就是上述现象。你在问类似的问题:

A b = new B();
b.bar();  // error

我们在这里出错的原因是因为不能保证b会有一个bar()方法。就我们所知(或者更确切地说,编译器知道)而言,b可能是一个C有谁知道什么的实例。出于这个原因,我们必须执行显式转换:

A b = new B();
((B) b).bar();    

这是因为 Java 是静态类型的(即使它执行动态绑定)。

于 2013-10-21T02:19:15.683 回答
2

实例方法在运行时根据其动态类型解析。这是多态性/后期绑定。无论您将对象转换为静态类型Object,它的运行时类型仍然是String,因此String#equals(Object)将被使用。

为什么我们可以向上而不是向下。

给定两个类

public class A {

}

public class B extends A {
    public void doSomething() {}
}

A a = new B();
a.doSomething(); // this won't compile because A doesn't declare a doSomething() method
((B) a).doSomething(); // this is fine because you are now calling the method on the static type B
// you might get a ClassCastException here if the runtime type of a wasn't B
于 2013-10-21T02:19:43.350 回答
1

由于所有方法在 java 中都是默认虚拟的,因此即使您将其类型转换为Object它也会调用String equals方法,因为该对象的类型String不是Object.

这也称为后期绑定或运行时多态性。

于 2013-10-21T02:19:35.140 回答
0

这不是 Java 解决应该使用哪种方法的方式。即使您在运行时将其转换为对象,也会使用字符串的等号。并且字符串的 equals 不检查引用相等,但如果字符串“逻辑上”相等。

这是由于所谓的“动态链接”,您可以在 Google 上搜索或尝试在此处阅读。

于 2013-10-21T02:17:08.707 回答
-1

String Object 是不可变对象之一,其他对象如 Integer。

所以这里是一个简单的比较,你创建了 2 个 Integer 对象(相同的值)并做相等的操作。返回 2 个整数相等更有意义。

从这个例子中,我想你现在可能知道不可变类的目标:它们旨在保留它们的状态并简化与它们相关的操作,就像 int 一样。

于 2013-10-21T02:20:47.423 回答