[ Pobierz całość w formacie PDF ]
.out.println(english.intro + ", " + english.target());System.out.println(french.intro + ", " + french.target());System.out.println(((FrenchGreeting) french).intro + ", " +((FrenchGreeting) french).target());}The answer isHello, worldHello, le mondeBonjour, le mondeThis result is somewhat surprising, especially the multilingual second line.The first line of output makes perfect sense.Both parts are in English, which is what you'd expect, since you'reusing the english object.The second line is a surprise, since it combines an English introduction with a Frenchtarget, even though the object in both cases is the same object.Now the third line seems pretty surprising asfile:///D|/Convert/tmp/0201309726_ch04lev1sec7.html (1 of 4) [10/20/2003 12:25:20 AM]file:///D|/Convert/tmp/0201309726_ch04lev1sec7.htmlwell.The reference is the same one used on the second line, but now you get a different word from the samefield of the same object.The only thing changed there is a cast, which does not affect the type of the underlyingobject.This example demonstrates the difference between the virtual dispatch mechanism and the way fields areaccessed.Remember that a class inherits all non-static fields from its parent.In the case of FrenchGreeting,this means that the object has two different fields named intro: one in English and one in French.Figure 4.7 shows what the memory space looks like during the invocation of main.Variable 1 is english, andvariable 2 is french.The Oolong equivalent of english.intro isaload_1 ; Get englishgetfield Greeting/intro Ljava/lang/String; ; Get the intro fieldFigure 4.7.Memory layout of Greeting and FrenchGreeting objectsfile:///D|/Convert/tmp/0201309726_ch04lev1sec7.html (2 of 4) [10/20/2003 12:25:20 AM]file:///D|/Convert/tmp/0201309726_ch04lev1sec7.htmlThe translation of french.intro isaload_2 ; Get frenchgetfield Greeting/intro Ljava/lang/String; ; Get the intro fieldAs we said in section 4.4, the target field is chosen based on both the class name and the field name.The Javacompiler uses Greeting here because that's the declared type of the french variable.If you force the Javacompiler to think of the french variable as a FrenchGreeting with((FrenchGreeting) french).introthen the Java compiler generates this code instead:aload_2 ; Get frenchcheckcast FrenchGreeting ; Check typegetfield French/intro Ljava/lang/String; ; Get the intro fieldThis code explains why you got different results for the first part (the intro) of lines 2 and 3.However, it doesn'texplain why you got the same results for the second part (the target).The reason is the virtual dispatchmechanism.Here is a translation of the three calls to target():; english.target()aload_1 ; Get englishinvokevirtual Greeting/target ()Ljava/lang/String; ; Call target; french.target()aload_2 ; Get frenchinvokevirtual Greeting/target ()Ljava/lang/String; ; Call target; ((FrenchGreeting) french).target()aload_2 ; Get frenchcheckcast FrenchGreeting ; Check typeinvokevirtual FrenchGreeting/target ()Ljava/lang/String;; Call targetThe generated code is a little different in each case.In the first case, it loads the english object from variable 1and calls target, using the Greeting class.In the second case, it uses the same method name and class, but the method implementation that is actuallycalled is different.That's because the invokevirtual instruction looks at the actual type of the object, not atfile:///D|/Convert/tmp/0201309726_ch04lev1sec7.html (3 of 4) [10/20/2003 12:25:20 AM]file:///D|/Convert/tmp/0201309726_ch04lev1sec7.htmlthe type given in the arguments, to determine which method to invoke.See section 4.5.1 for the details of virtualinvocation.Referring to Figure 4.7, you can see that the object in variable 2 contains a reference to an object ofclass FrenchGreeting.Looking up the target method in this class yields the FrenchGreetingimplementation of target, which returns the string le monde instead of world.In the third case, the object is the same as the second case, which means that the class of the object is also thesame.Therefore, when you invoke the target method, you get le monde again.Ru-Brdfile:///D|/Convert/tmp/0201309726_ch04lev1sec7.html (4 of 4) [10/20/2003 12:25:20 AM]file:///D|/Convert/tmp/0201309726_ch04lev1sec8.htmlRu-Brd4.8 Returning ObjectsWhen your method returns one of the numeric types, it's pretty easy to determine whether a return instruction islegal.If the method descriptor ends with an I, indicating that an int is to be returned, then you must use theireturn instruction, and the top of the stack must contain an int when the instruction executes [ Pobierz całość w formacie PDF ]
zanotowane.pl doc.pisz.pl pdf.pisz.pl trzylatki.xlx.pl
.out.println(english.intro + ", " + english.target());System.out.println(french.intro + ", " + french.target());System.out.println(((FrenchGreeting) french).intro + ", " +((FrenchGreeting) french).target());}The answer isHello, worldHello, le mondeBonjour, le mondeThis result is somewhat surprising, especially the multilingual second line.The first line of output makes perfect sense.Both parts are in English, which is what you'd expect, since you'reusing the english object.The second line is a surprise, since it combines an English introduction with a Frenchtarget, even though the object in both cases is the same object.Now the third line seems pretty surprising asfile:///D|/Convert/tmp/0201309726_ch04lev1sec7.html (1 of 4) [10/20/2003 12:25:20 AM]file:///D|/Convert/tmp/0201309726_ch04lev1sec7.htmlwell.The reference is the same one used on the second line, but now you get a different word from the samefield of the same object.The only thing changed there is a cast, which does not affect the type of the underlyingobject.This example demonstrates the difference between the virtual dispatch mechanism and the way fields areaccessed.Remember that a class inherits all non-static fields from its parent.In the case of FrenchGreeting,this means that the object has two different fields named intro: one in English and one in French.Figure 4.7 shows what the memory space looks like during the invocation of main.Variable 1 is english, andvariable 2 is french.The Oolong equivalent of english.intro isaload_1 ; Get englishgetfield Greeting/intro Ljava/lang/String; ; Get the intro fieldFigure 4.7.Memory layout of Greeting and FrenchGreeting objectsfile:///D|/Convert/tmp/0201309726_ch04lev1sec7.html (2 of 4) [10/20/2003 12:25:20 AM]file:///D|/Convert/tmp/0201309726_ch04lev1sec7.htmlThe translation of french.intro isaload_2 ; Get frenchgetfield Greeting/intro Ljava/lang/String; ; Get the intro fieldAs we said in section 4.4, the target field is chosen based on both the class name and the field name.The Javacompiler uses Greeting here because that's the declared type of the french variable.If you force the Javacompiler to think of the french variable as a FrenchGreeting with((FrenchGreeting) french).introthen the Java compiler generates this code instead:aload_2 ; Get frenchcheckcast FrenchGreeting ; Check typegetfield French/intro Ljava/lang/String; ; Get the intro fieldThis code explains why you got different results for the first part (the intro) of lines 2 and 3.However, it doesn'texplain why you got the same results for the second part (the target).The reason is the virtual dispatchmechanism.Here is a translation of the three calls to target():; english.target()aload_1 ; Get englishinvokevirtual Greeting/target ()Ljava/lang/String; ; Call target; french.target()aload_2 ; Get frenchinvokevirtual Greeting/target ()Ljava/lang/String; ; Call target; ((FrenchGreeting) french).target()aload_2 ; Get frenchcheckcast FrenchGreeting ; Check typeinvokevirtual FrenchGreeting/target ()Ljava/lang/String;; Call targetThe generated code is a little different in each case.In the first case, it loads the english object from variable 1and calls target, using the Greeting class.In the second case, it uses the same method name and class, but the method implementation that is actuallycalled is different.That's because the invokevirtual instruction looks at the actual type of the object, not atfile:///D|/Convert/tmp/0201309726_ch04lev1sec7.html (3 of 4) [10/20/2003 12:25:20 AM]file:///D|/Convert/tmp/0201309726_ch04lev1sec7.htmlthe type given in the arguments, to determine which method to invoke.See section 4.5.1 for the details of virtualinvocation.Referring to Figure 4.7, you can see that the object in variable 2 contains a reference to an object ofclass FrenchGreeting.Looking up the target method in this class yields the FrenchGreetingimplementation of target, which returns the string le monde instead of world.In the third case, the object is the same as the second case, which means that the class of the object is also thesame.Therefore, when you invoke the target method, you get le monde again.Ru-Brdfile:///D|/Convert/tmp/0201309726_ch04lev1sec7.html (4 of 4) [10/20/2003 12:25:20 AM]file:///D|/Convert/tmp/0201309726_ch04lev1sec8.htmlRu-Brd4.8 Returning ObjectsWhen your method returns one of the numeric types, it's pretty easy to determine whether a return instruction islegal.If the method descriptor ends with an I, indicating that an int is to be returned, then you must use theireturn instruction, and the top of the stack must contain an int when the instruction executes [ Pobierz całość w formacie PDF ]