[英]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
不会改变。 但是,局部变量(表示参数)将指向由坐标定义的新Point
: 0,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.