我在IB的API中声明实例变量时看到this
,但这似乎是一个坏主意。是否保证在完全构造this
后进行分配?这有关系吗?
我认为实例变量是在构造函数之前初始化的,因为它们可以被构造函数使用。如果使用this
会有例外吗?
如果它以某种方式起作用,那似乎不是一个好主意 - second
的{{1}}构造函数是否可用?如果是,FirstClass
之前是SecondClass
构建的吗?这意味着FirstClass
最终为3而num
为10?或者会出现运行时错误吗?甚至有任何保证吗?
i
我想IB有一个非常扎实的开发团队,知道他们在做什么。你怎么看:
public class FirstClass {
SecondClass second = new SecondClass(this);
public int i = 3;
FirstClass(){
i = second.DoSomething();
}
}
public class SecondClass{
private int num = 10;
SecondClass(FirstClass first){
num = first.i;
}
public int DoSomething(){
return num;
}
...
}
使用初始化实例变量吗?修改
答案是肯定的是有保证的结果(现在 - 但继续阅读......),但是不应该这样做,因为很容易无意中更改代码可能会改变这个'保证'的结果
我现在知道在构建新对象(例如this
)时JVM:
FirstClass
被初始化为3。second
并在{{{}之前返回1}}构造函数正在运行。这样做的原因很糟糕,“保证”结果可以通过两种方式改变:
second
之前初始化FirstClass
),结果将会更改。很容易不去注意这一点。所以看起来IB的API会受到这种美味的影响,我现在必须牢记这一点。
感谢Emil H的回答和他对本文的指导,这最终促使我理解上述内容:http://www.artima.com/designtechniques/initializationP.html - 强烈推荐阅读。
还要感谢Alexander Drobyshevsky在答案中提出了非常相似的观点。
答案 0 :(得分:1)
当然,有时你必须使用它,例如当通过构造函数给出的变量被调用为与实例变量相同时:
int count;
public Test(int count){
this.count = count;
}
答案 1 :(得分:0)
是的,this
(在内部是构造中对象的“指针”)可以在构造函数中使用。
一个愚蠢的例子可能是一个自我引用的类
class MySelf {
Myself _me;
public MySelf() { _me = this; }
}
还有更现实的例子。想象一下,你想要一个类来表示一个数学图形,你可以用连接到它自身的单个元素进行初始化。
答案 2 :(得分:0)
有趣的问题。在您描述的情况下发生的情况是,当您调用new FirstClass()
时,类加载器会查找该类并在未加载时加载它。然后它似乎创建了FirstClass
的实例,其中所有字段都有其默认值,例如second为null,i为0。
然后,类加载器加载SecondClass
。创建并初始化SecondClass
的实例,将num
字段设置为10.然后构造函数调用传入FirstClass
实例(字段具有已初始化为的值)那一点)。因此num
中SecondClass
的值将在构造函数中设置为0。
SecondClass
构造函数完成后,对象get被分配到second
中的FirstClass
字段(仍在初始化)。在此之后i
被初始化为3.现在FirstClass
的构造函数被调用,并且我被赋予了DoSomething()
的返回值,在这种情况下将为0.
如需进一步参考,请查看:http://www.artima.com/designtechniques/initializationP.html 它给出了对象初始化的描述。
<强> TL; DR 强> 所以回答你的问题:
this
。答案 3 :(得分:0)
这有两种可能的Java变体; 首先,是您希望引用全局变量(来自外部范围)。 e.g:
class First {
private int x;
public void setX(int x) {
this.x = x; // outer x is equal to the parameter
}
}
另一个用途,就是引用当前对象的构造函数。 e.g:
public Color {
private int red, green, blue;
public void Color(int r, int g, int b) {
red = red;
green = g;
blue = b;
}
public void setColor(int r, g, b) {
this(r,g,b);
}
}
通过使用3个参数调用此(1,2,3)来告诉编译器您希望引用带有3个参数的构造函数。
希望有所帮助!
答案 4 :(得分:0)
起初,这是一个不好的方法。您必须避免使用这些结构:使用未完全初始化的变量。 有时候使用“模板方法”设计模式可能会有所帮助。
正是在你的例子中,在这种情况下,在执行FirstClass构造函数之后,i = 0的结果值;它取决于FirstClass中i的赋值顺序。如果您通过下一种方式更改分配顺序:
public int i = 3;
SecondClass second = new SecondClass(this); // just order changed
在FirstClass构造函数执行完后,你得到答案i = 3.
this - 仅引用当前的类实例。它已经存在于您的类实例变量开始初始化时。首先,所有变量都有其默认值(object为null,int为0等)。在第二个初始化所有简单的赋值,如“int i = 3”,之后执行当前类的超级构造函数,最后执行当前类的构造函数。简单变量按类中的顺序初始化为up,但是你不应该依赖它。