Java 为什么要使用“函数”;显示();自动放置在构造函数中
下面是我有两个类实际上什么都不做的代码。当选中“类测试床”的反编译代码时,“int val=tb.display()”将自动放入构造函数中。这是怎么发生的Java 为什么要使用“函数”;显示();自动放置在构造函数中,java,Java,下面是我有两个类实际上什么都不做的代码。当选中“类测试床”的反编译代码时,“int val=tb.display()”将自动放入构造函数中。这是怎么发生的 class TestBed { int display() { return 100; } TestBed tb; int val = tb.display(); /* will get placed in constructor
class TestBed
{
int display()
{
return 100;
}
TestBed tb;
int val = tb.display(); /* will get placed in constructor
automatically. But how? */
}
public class DeleteThis {
public static void main(String[] args) {
System.out.println("printing");
}
}
使用反编译器反编译“TestBed.class”后,出现以下代码
/* Following is decompiled code */
class TestBed
{
TestBed tb;
int val;
TestBed()
{
val = tb.display(); /* How int val = tb.display() gets placed
in constructor automatically */
}
int display()
{
return 100;
}
}
您的字段
val
的值等于tb。显示。所有字段都使用默认值(0表示int
)和构造函数中的其他预定义用户值初始化。所以方法tb.display在构造函数中被调用。我认为这种行为没有什么特别的原因
不过,通常情况下,变量是在构造函数内部实例化的,反编译器可能只是使用这个标准。在这种情况下,两段代码的效果应该完全相同
无论如何,val
将设置为tb.display()代码>实例变量初始化实际上是由编译器放入构造函数中的
请参见这是因为*.class文件的格式。将*.java文件编译为*.class文件时,所有以字段var
的方式初始化的实例字段(即:T myVar=myValue
)都将在构造函数的代码中初始化
对课程格式的简要且不完整的描述:
类格式由不同类型的“结构”组成,其中两种是字段结构(在其中注册了字段var
)和方法结构(代码仅位于这种结构的“code”属性下)
字段结构没有空间容纳代码(用于初始化您的代码var:int val=tb.display();
),因此需要将其放入与构造函数对应的方法结构的“code”属性中
查看以获取更多详细信息(尝试用几句话解释这里的所有内容会太复杂)运行时由于tb变量尚未初始化,上述代码会出现空指针异常
由于类级变量的初始化必须在类实例化时进行,编译器将代码放在构造函数中
尝试用一些参数定义一个显式构造函数,并通过下面的更改尝试另一种方法
static TestBed tb;
static int val = tb.display();
您的变量TestBed tb
尚未初始化,您正在调用,int val=tb.display()代码>将引发异常。您没有得到异常的原因是您没有在main()
中的任何位置实例化类TestBed
,此时您将代码更改为:-
public class DeleteThis {
public static void main(String[] args) {
TestBed tb=new TestBed();
System.out.println("printing");
}
您将得到nullpointer异常
您在反编译器中获得该代码的原因就是因为这样,从a读取(找不到javadocs源代码的链接:)
Java编译器自动生成实例字段初始化代码,并将其放入类的构造函数中。初始化代码按其在源代码中出现的顺序插入到构造函数中
因此,编译器将int val=tb.display()
分解为
int val;
TestBed(){
val=tb.display();
}
嘿,我在这里并没有实例化任何东西,在实例化过程中,放置在构造函数外部的所有变量都将根据其类型被赋予null或0,并且所有放置在构造函数内部的变量都将被赋予给定的值。但在这里,我只是从测试台tb调用display()方法,出于某种原因,tb.display()被放置在构造函数中。原因是什么?@priyankjain否,您正在使用display()
初始化val
,这是一个实例变量,因此初始化必须在构造时进行。变量本身将被设置为0或null,但如果它们已经被设置为某个值,则不会。在这两种情况下,val
将等于100,无论您将代码放置在何处。它将编译tb
将默认值初始化为null
。是的,这是真的,但在下一行OP写入int val=tb.display()代码>,因为默认情况下tb被初始化为null
,所以您不能像tb.display()
那样调用它的方法,而且由于编译器不会执行tb=new TestBed()
,所以它应该给出与不编译不同的null指针异常:)。