繁体   English   中英

Java中构造函数中的最终参数

[英]Final parameters in a constructor in Java

我正在学习Java中的类和构造函数。 我在一个示例程序中乱用代码,似乎无法弄清楚到底发生了什么。

这段代码不会编译对我来说有意义:

class Line {
Point start;
Point end;

Line(final Point start, final Point end) {

    this.start = new Point(start);
    this.end = new Point(end);
    start = new Point(0.4, 0.4);

}...

我试图通过调用Point对象的构造函数将原始的起始点对象引用分配给另一个Point对象。 final关键字与此冲突。

但是当我从Point start参数中删除final关键字时......

class Line {
Point start;
Point end;

Line(Point start, final Point end) {

    this.start = new Point(start);
    this.end = new Point(end);
    start = new Point(0.4, 0.4);

}

它似乎没有实际更改引用,传递给Line构造函数的Point对象仍然似乎指向原始对象,并且由Line构造函数的代码保持不变。 什么给出了什么? 这是否与引用的'start'在Line构造函数的作用域中是本地的这一事实有关?

Java不使用pass-by-reference,它使用ALWAYS pass-by-value。 实际上,Java中的引用类型只是指针,并不像C#中的引用那样共享相同的含义。

所以当你在构造函数中执行此语句时:

start = new Point(0.4, 0.4);

传入参数的原始Point不会改变。 但是,局部变量(表示参数)将指向由坐标定义的新Point0,4, 0,4

为了更好地理解,请阅读这篇文章: Java是Pass-by-Value,Dammit!

该变量是构造函数的本地变量。 因此,在构造函数之外为其分配新引用没有意义,因为它不存在于构造函数之外。

实现这种效果的一种方法是将其包装在另一个对象中。 并传递对可变包装器的引用。

它似乎并没有真正改变参考

您无法更改用于在该方法内调用方法的参数的引用。 参数的值(对象的引用)将复制到方法参数中,因此您可以对同一对象进行第二次引用。 在方法内部,您只能修改第二个引用,并且不能更改原始引用。 你唯一能做的就是修改引用的对象。

当您执行“start = new Point(0.4,0.4);”时,您将引用构造函数上收到的开头。 由于构造函数将其定义为final,因此将非新值赋值给变量是非法的。

细节是,当java使用pass-by-value方法时,即使你不使用final并更改构造函数中的值,原始值的值(作为参数传递给方法的值)仍然是相同。

从“Line(Point start,final Point end){”初始化之后,通过执行“this.start = new Point(start)”来修改“start”时,你没有替换堆上的实际对象是什么“开始”点但是在堆上的新Point对象与现有的单独区域分配并修改现有指针“start”(STACK上的标量类型)以指向新分配。

构造函数是一种特殊用途的方法(函数),在java堆上进行对象分配后由java的new运算符调用。 因此,当调用方法时,会分配堆栈,并且在堆栈(不是堆)上分配方法中的任何标量类型(在java中它的原始类型,如int,double,char ...)和REFERENCE。 当您将状态写为“final Object o = new Object()”时,您已在内存中分配了两个内容。
首先,java堆上的“new Object()”。 (堆)
第二,指向堆栈上方的指针,即“对象o”。 (堆)
在您的情况下,您只是尝试覆盖标量类型的“最终对象o”,并且仅在jvm内存(STACK)上读取。

class Line {
Point start;
Point end;

// On the first line "Line(Point start, Point end) {",
// two references and two actual Objects that references point to
// are already allocated in memory.  
// So you've allocated four things.
Line(Point start, final Point end) { // "start" initialized on stack as final
    this.start = new Point(start); // tried to modify final variable on stack.
    this.end = new Point(end);
    start = new Point(0.4, 0.4);

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM