【问题标题】:Polymorphism, Casting to Object, and Type Erasure多态性、对象转换和类型擦除
【发布时间】:2015-04-16 15:23:03
【问题描述】:

这是我在 Stackoverflow 上的第一个问题,我希望你能帮助我解决我现在遇到的理解问题。

假设我正在这样做:

Object o = null;
String s = "Test";
System.out.println(o instanceof String); //This returns false
o = s;
System.out.println(o instanceof String); //This returns true

到目前为止一切都很好,但现在当我这样做时:

System.out.println( ((Object) o) instance of String) //Still prints true

那么为什么即使在打印中我将 o 转换回 Object 类,这个语句也会打印出 true 呢?甚至

System.out.println(((Object)o).getClass()) 

打印出 o 属于 String 类。为什么会这样?

这引出了我的第二个问题,它与泛型和类型擦除有关。 我查看了这样的代码示例:

private static <T> T cast(Object i){
    return (T) i;
}

public static void main(String[] args){
    Object o = null;
    try{
        o = main.<Double> cast("Test");
    }catch(ClassCastException ex) {
        System.out.println("Could not cast properly");
    }

    System.out.println(o == null); //Prints false
    System.out.println(o instanceof String); //Prints true
    System.out.println(o instanceof Double); //Prints false
}

根据我对类型擦除的理解,所有泛型 T 将在运行时替换为 Object。运行强制转换功能时,实际上应该发生的事情是 类似于return (Object) i; 的东西。 作为我上面的第一个问题,为什么System.out.println(o instanceof String); 打印为真? o 不应该是 Object 类型吗?

期待您的回答,谢谢:)!

【问题讨论】:

  • Assax91,请重新命名此问题并为您的第二个问题创建第二个问题。问题被分离出来,以帮助为未来的编码人员提供最有用的存档。
  • 至少合适的标签都有了……你觉得够了吗?
  • @Choirbean 我认为这个问题很好。这些问题都是相关的。
  • 我的目标是将第一个问题作为第二个问题的介绍,因为我认为它们基本上是相同的问题。这是一个更大的问题,分为两部分。那么该怎么走呢?拆分还是保留?
  • 我想我在这里被否决了。我会提出两个问题并将第二个问题与第一个问题联系起来,但我不介意犯错。我经常错:)

标签: java casting polymorphism type-erasure


【解决方案1】:

那么为什么即使在打印中我将 o 转换回 Object 类,这个语句也会打印出 true 呢?

您只是将引用投射到Object。实际对象仍然是String 类型的对象。并且instanceof 检查是针对实际实例,而不是引用类型。

打印出 o 属于 String 类。为什么会这样?

getClass() 方法返回运行时对象类型的 Class 实例。

为什么 System.out.println(o instanceof String);打印是真的吗?

如您所见,您将 String 类型作为参数传递给您的 cast() 方法。因此,即使引用类型是Object,实际对象也是String 类型。由于泛型,这里没有什么特别的。道理一样,结果也一样。

【讨论】:

  • (1) 首先感谢您的快速回复。但是,仍然有一些让我感到困惑的事情。由于 o 基本上是指向我记忆中某物的指针并且我正在投射引用,所以我不是直接对存储在 o 中的东西采取行动吗?是不是就像函数直接作用于对象一样,因为对象在 Java 中是通过引用传递的(与原语相反)? (2) 我希望从强制转换函数中返回一个对象,而不是字符串,因为我明确地返回了对象,但我认为这是我弄错了基础知识。我想我应该再次阅读书籍!
  • @Assax91 在 Java 中一切都是按值传递的。没有指针之类的东西。你得到的是对一个对象的引用。将其转换为单独的引用将产生一个新的引用类型,它也指向同一个对象。所以,底层对象没有改变。
  • 哦,该死的,再次阅读您的答案后,我想我现在明白了! Instanceof 检查给定引用处对象的类,而不是引用本身的类型。因此,即使我将 o 转换为 Object,该地址的内容仍然是一个字符串。谢谢!编辑:被你忍着了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
  • 2015-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多