我已经浏览了网络上的大部分论文,但我仍然不能理解,为什么我们必须使用向上预测。
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();
}
}您可以考虑将此示例用于向上转换。这里向上转换的用处是什么?d和a都给出了相同的输出!
发布于 2011-03-19 20:34:30
在大多数情况下,显式向上转换是完全不必要的,也没有任何效果。
在您的示例中,显式向上转换
Animal a = (Animal)d;可以替换为以下内容:
Animal a = d; // implicit upcast隐式向上转换(针对Java对象类型)的目的是“忘记”静态类型信息,以便可以在需要更通用类型的情况下使用具有特定类型的对象。这会影响编译时类型检查和重载解析,但不会影响运行时行为。
(对于基元类型,向上转换会导致转换,在某些情况下可能会导致精度损失;例如,long -> float。)
但是,在某些情况下,显式上转换的存在会改变语句/表达式的含义。
在Java中有必要使用向上转换的一种情况是,当你想强制使用一个特定的方法重载时;例如,假设我们有重载的方法:
public void doIt(Object o)...
public void doIt(String s)...如果我有一个字符串,并且我想调用第一个重载而不是第二个重载,我必须这样做:
String arg = ...
doIt((Object) arg);一个相关的案例是:
doIt((Object) null);如果没有类型转换,代码将无法编译。我不确定这是否算作向上转换(参见JLS 5.1.13最后一段),但无论如何都应该提到它。
第二种情况涉及可变参数:
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.第三种情况是在原始数值类型上执行操作时;
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发布于 2011-03-19 20:25:55
在java中需要使用向上广播吗?
不确定您是否理解正确的术语,但这里是a quote来澄清:
向上转换
执行从派生类到更通用基类的转换。
这里有一个场景,它确实很重要:
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
发布于 2011-03-19 20:19:09
向上转换在你的例子中绝对没有任何意义(事实上,我无法想象有任何情况下它有),应该避免,因为它只会让开发人员感到困惑。一些IDE(肯定是IntelliJ)会在这一行中发出警告,并建议删除向上转换)。
EDIT:此代码给出相同的结果,因为Java中的所有对象方法都是虚拟的,这意味着目标方法是在运行时由对象的实际类型发现的,而不是通过引用类型发现的。尝试将callme()设为静态,看看会发生什么情况。
https://stackoverflow.com/questions/5361999
复制相似问题