2013-10-28 22 views
0

正如我刚才的问题Java method invocation order方法调用顺序引用

如果我的代码更改

public class MyClassTest { 

    private static MyClass m = new MyClass(10); 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     m.initMe(getint()); 
    } 

    public static int getint() { 
     m = new MyClass(20); 
     return 40; 
    } 
} 

class MyClass { 
    private int i; 

    public MyClass(int i) { 
     this.i = i; 
    } 

    void initMe(int i) { 
     System.out.println(this.i); 
    } 
} 

我的输出为10不是20造成Java是通过按值吗? 所以同样重要的是,方法调用顺序也受到对象引用与运行时类型对齐的影响。

+2

你到底想干什么? –

回答

0

m.initMe(getint());它指示调用由m引用的Object的方法。

现在,如果m在执行期间引用一个新对象,但指令将明确地调用旧对象的方法。一旦完成,Object将无法访问,并且也会被垃圾收集。

-1

这是执行下面的行时发生的情况。

m.initMe(getint()); 

m其被参照包含10值的对象被用于调用initMe()方法。现在发布initMe()的调用后,您使m引用getint()方法中的新对象引用。

但由于initMe()在新作业之前被调用,this.i返回10而不是20

在此之后,m将新对象的i值指定为20。如果在第一个语句后添加另一行m.initMe(getint());,则将从第二个语句执行中获得。


所以它也很重要的是方法调用顺序还受 对象引用与运行时类型对准

因此,答案是,顺序很重要。

+0

Downvoter - 谨慎评论你为什么不同意我? – SudoRahul

0

你看,在这里你创建一个新的MyClass为10的值:

private static MyClass m = new MyClass(10); 

现在,this.i10,因为,你说的应该是10

它不返回20的原因是因为当你拨打:

m.initMe(getint()); 

它将返回10,因为它是在initMe()通话的时间分配给m值。


如果你这样做:

public static void main(String[] args) { 
     m = new MyClass(20); 
     m.initMe(getint()); 
    } 

    public static int getint() { 
     return 40; 
    } 

你: 20,因为现在你已经分配的20一个价值,你的对象之前的initMe()执行。


有趣的是,如果你这样做:

public static void main(String[] args) { 
     m.initMe(getint()); 
     m.initMe(getint()); 
    } 

    public static int getint() { 
     m = new MyClass(20); 
     return 40; 
    } 

你:

10 
20 

,因为在第一次运行时,该值将10,但m被分配一个值现在为20,而在下一次运行之前,执行前,它将保留值20

0

如何回答上一个问题,JVM是基于堆栈的机器。首先运行MyClass(10)的初始化实例的静态部分。在此之后,执行main(),其中MyClass(10)的实例将被推送到操作数堆栈(0: getstatic #2)。在此之后,将执行getint(),其中将创建MyClass(20)的新实例(6: invokespecial #6)并设置新的静态字段(9: putstatiC#2),但在操作数堆栈仍为旧值(MyClass(10))。

static {}; 
Code: 
    0: new   #5     // class MyClass 
    3: dup 
    4: bipush  10 
    6: invokespecial #6     // Method MyClass."<init>":(I)V 
    9: putstatic  #2     // Field m:LMyClass; 
    12: return 
LineNumberTable: 
    line 3: 0 

public static void main(java.lang.String[]); 
    Code: 
    0: getstatic  #2     // Field m:LMyClass; 
    3: invokestatic #3     // Method getint:()I 
    6: invokevirtual #4     // Method MyClass.initMe:(I)V 
    9: return 
    LineNumberTable: 
    line 7: 0 
    line 8: 9 

public static int getint(); 
    Code: 
    0: new   #5     // class MyClass 
    3: dup 
    4: bipush  20 
    6: invokespecial #6     // Method MyClass."<init>":(I)V 
    9: putstatic  #2     // Field m:LMyClass; 
    12: bipush  40 
    14: ireturn 
    LineNumberTable: 
    line 11: 0 
    line 12: 12