Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 向下浇铸的对象指向哪里? 我的问题:_Java_Downcast - Fatal编程技术网

Java 向下浇铸的对象指向哪里? 我的问题:

Java 向下浇铸的对象指向哪里? 我的问题:,java,downcast,Java,Downcast,为什么h.n在h=(马)ah之后仍然打印7?赋值后,它应指向ah指向的同一对象,n字段指向5 首先,让我们调用类Animal的n字段“Animal.n”以避免混淆 与方法不同,字段不受重写的约束。因此,在您的Horse类中,您可能认为您正在用7覆盖Animal.n的值,实际上您正在声明一个名为n的新变量(我们称之为Horse.n,以避免混淆) 实际上,您有一个名为Horse的类,它有两个字段:Animal.n和Horse.n。当您说“n”时,会得到哪个字段取决于当时变量的静态类型 如果对象的类型

为什么
h.n
h=(马)ah
之后仍然打印7?赋值后,它应指向
ah
指向的同一对象,n字段指向5

首先,让我们调用类
Animal
n
字段“
Animal.n
”以避免混淆

与方法不同,字段不受重写的约束。因此,在您的Horse类中,您可能认为您正在用7覆盖
Animal.n
的值,实际上您正在声明一个名为
n
的新变量(我们称之为
Horse.n
,以避免混淆)

实际上,您有一个名为
Horse
的类,它有两个字段:
Animal.n
Horse.n
。当您说“
n
”时,会得到哪个字段取决于当时变量的静态类型

如果对象的类型为
Horse
,但向上转换为
Animal
,则
n
字段引用
Animal.n
,其值为“5”。因此,
ah.n
是“5”

当您拥有相同的对象时,再次向下转换到
n
字段引用
Horse.n
,其值为“7”。因此
h.n
为“7”

澄清:事实上,
h
确实指向了
ah
指向的同一个对象——向下投射不会改变被指向的对象。但是,静态类型确实会影响请求对象的哪个字段。

在Java中创建的每个对象(称为实例)都指向从中创建它的类。这是对象的真实类型,在对其强制转换引用时不会更改。类似地,引用对象的每个变量都有一个声明的类型。这就是编译器将如何处理对象并确定允许哪些操作


然而,这两种类型只是松散耦合的。强制转换对象引用仅更改声明的类型。它不影响对象的行为,只影响编译器如何处理它。

讨论字段不受重写的原因:重写方法的关键是使用相同的接口,但具有不同的实现。由于字段没有实现,只有类型和名称,所以重写不会做任何事情。这里您可能需要的是Horse构造函数分配
a=7
,而不是声明一个新的int。这样,Horse将只有一个名为
a
的字段,该字段被明确地设置为7。对于一个奇怪的问题,这是一个很好的解释。我们最好把所有字段都保密D@maaartinus的确如果所有字段都是私有的,那么就永远不会出现这种情况。但我确实认为拥有受保护的字段有一些好处(理想情况下不是,但实际上它可以节省大量时间,并且仍然具有私有字段的大部分好处),在这种情况下,这个问题仍然是相关的。@mgiuca:什么时候可以安全?所有访问器都可以内联,所以你的意思是输入时间,对吗?我更喜欢使用lombok,为我制作访问器。@maaartinus是的,我指的是程序员时间,而不是执行速度。我个人不喜欢自动生成代码的工具。这不仅仅是键入时间——还有使用更多方法维护更大代码库的成本,还有键入
a.setX()
而不是一直键入
a.x=
的成本,以及随之而来的可读性。对于公共领域,我认为这种折衷是值得的(为一个健壮的接口付出努力要好得多),但是对于受保护的领域,我不认为会有回报,除非你正在编写一个库包。我是这个论坛的新手。我没有发表任何评论。有人改了。我知道它打印7,5,7。然后我看到有人把它换了。然后我看到了你的评论。我批准了你的编辑。但我没有批准第一个?它是如何改变的?我知道不是你添加了这些评论。谢谢你批准我的编辑。比我名声大的人(我想是2000人)可以不经你的批准就编辑,所以这就是之前发生的事情。在将来,最好提供您看到的输出。谢谢谢谢你的回答:)另外,如果你认为我的答案完全回答了问题,你能勾选“接受答案”复选框吗?干杯。也就是说,静态类型指的是引用变量类型,对吗?
public class Animal{

    int n = 5;

    public static void main(String[] args) {

        Animal a = new Animal();
        Animal ah = new Horse();
        Horse h = new Horse(); 

        System.out.println(h.n); // prints 7
        System.out.println(ah.n); // prints 5
        h = (Horse) ah;
        System.out.println(h.n); // prints 7

    }
}

class Horse extends Animal{

    int n = 7;

}