首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java中使用Upcasting有什么必要呢?

在java中使用Upcasting有什么必要呢?
EN

Stack Overflow用户
提问于 2011-03-19 20:15:30
回答 8查看 40.5K关注 0票数 18

我已经浏览了网络上的大部分论文,但我仍然不能理解,为什么我们必须使用向上预测。

代码语言:javascript
复制
class Animal 
{ 
    public void callme()
    {
        System.out.println("In callme of Animal");
    }
}

class Dog extends Animal 
{ 
    public void callme()
    {
        System.out.println("In callme of Dog");
    }

    public void callme2()
    {
        System.out.println("In callme2 of Dog");
    }
}

public class UseAnimlas 
{
    public static void main (String [] args) 
    {
        Dog d = new Dog();      
        Animal a = (Animal)d;
        d.callme();
        a.callme();
        ((Dog) a).callme2();
    }
}

您可以考虑将此示例用于向上转换。这里向上转换的用处是什么?da都给出了相同的输出!

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2011-03-19 20:34:30

在大多数情况下,显式向上转换是完全不必要的,也没有任何效果。

在您的示例中,显式向上转换

代码语言:javascript
复制
    Animal a = (Animal)d;

可以替换为以下内容:

代码语言:javascript
复制
    Animal a = d;    // implicit upcast

隐式向上转换(针对Java对象类型)的目的是“忘记”静态类型信息,以便可以在需要更通用类型的情况下使用具有特定类型的对象。这会影响编译时类型检查和重载解析,但不会影响运行时行为。

(对于基元类型,向上转换会导致转换,在某些情况下可能会导致精度损失;例如,long -> float。)

但是,在某些情况下,显式上转换的存在会改变语句/表达式的含义。

在Java中有必要使用向上转换的一种情况是,当你想强制使用一个特定的方法重载时;例如,假设我们有重载的方法:

代码语言:javascript
复制
public void doIt(Object o)...
public void doIt(String s)...

如果我有一个字符串,并且我想调用第一个重载而不是第二个重载,我必须这样做:

代码语言:javascript
复制
String arg = ...

doIt((Object) arg);

一个相关的案例是:

代码语言:javascript
复制
doIt((Object) null);

如果没有类型转换,代码将无法编译。我不确定这是否算作向上转换(参见JLS 5.1.13最后一段),但无论如何都应该提到它。

第二种情况涉及可变参数:

代码语言:javascript
复制
public void doIt(Object... args)...

Object[] foo = ...

doIt(foo);  // passes foo as the argument array
doIt((Object) foo); // passes new Object[]{foo} as the argument array.

第三种情况是在原始数值类型上执行操作时;

代码语言:javascript
复制
int i1 = ...
int i2 = ...
long res = i1 + i2;           // 32 bit signed arithmetic ... might overflow
long res2 = ((long) i1) + i2; // 64 bit signed arithmetic ... won't overflow
票数 25
EN

Stack Overflow用户

发布于 2011-03-19 20:25:55

在java中需要使用向上广播吗?

不确定您是否理解正确的术语,但这里是a quote来澄清:

向上转换

执行从派生类到更通用基类的转换。

这里有一个场景,它确实很重要:

代码语言:javascript
复制
class A {
}

class B extends A {
}

public class Test {

    static void method(A a) {
        System.out.println("Method A");
    }

    static void method(B b) {
        System.out.println("Method B");
    }

    public static void main(String[] args) {
        B b = new B();
        method(b);                      // "Method B"

        // upcasting a B into an A:
        method((A) b);                  // "Method A"
    }
}

这里描述了另一种更微妙的情况(与访问修饰符相关):Java Oddity: How an upcast can save the day

票数 10
EN

Stack Overflow用户

发布于 2011-03-19 20:19:09

向上转换在你的例子中绝对没有任何意义(事实上,我无法想象有任何情况下它有),应该避免,因为它只会让开发人员感到困惑。一些IDE(肯定是IntelliJ)会在这一行中发出警告,并建议删除向上转换)。

EDIT:此代码给出相同的结果,因为Java中的所有对象方法都是虚拟的,这意味着目标方法是在运行时由对象的实际类型发现的,而不是通过引用类型发现的。尝试将callme()设为静态,看看会发生什么情况。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5361999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档