⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap08.html

📁 Inside the java virtualMachine,深入研究java虚拟机
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<P>&nbsp;</P>
<P>    public static void main(String[] args) {</P>
<P>        if (AntHill.debug) {</P>
<P>            System.out.println("Debug is true!");</P>
<P>        }</P>
<P>    }</P>
<P>}</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></FONT><FONT FACE="Courier New">end</FONT></P></PRE>
<P>Because of the special treatment of primitive constants, the Java compiler can decide whether or not to include the body of the <FONT FACE="Courier New">if</FONT> statement in <FONT FACE="Courier New">Example2.main()</FONT> depending upon the value of <FONT FACE="Courier New">AntHill.debug</FONT>. Because <FONT FACE="Courier New">AntHill.debug</FONT> is <FONT FACE="Courier New">true</FONT> in this case, <FONT FACE="Courier New">javac</FONT> generates bytecodes for <FONT FACE="Courier New">Example2</FONT>韘 <FONT FACE="Courier New">main()</FONT> method that include the body of the <FONT FACE="Courier New">if</FONT> statement, but not a check of <FONT FACE="Courier New">AntHill.debug</FONT>韘 value. The constant pool of <FONT FACE="Courier New">Example2</FONT> has no symbolic reference to class <FONT FACE="Courier New">AntHill</FONT>. Here are the bytecodes for <FONT FACE="Courier New">main()</FONT>:</P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">              // Push objref from System.out
<P>0 getstatic #8 &lt;Field java.io.PrintStream out</FONT></P>
<P>              // Push objref to literal string "Debug is true!"</P>
<P>3 ldc #1 &lt;String "Debug is true!"</FONT></P>
<P>              // Pop objref (to a String), pop objref(to</P>
<P>              // System.out), invoke println() on System.out</P>
<P>              // passing the string as the only parameter:</P>
<P>              // System.out.println("Debug is true!");</P>
<P>5 invokevirtual #9 &lt;Method void println(java.lang.String)</FONT></P>
<P>8 return      // return void</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></FONT><FONT FACE="Courier New">end</FONT></P></PRE>
<P>If the reference to <FONT FACE="Courier New">AntHill.debug</FONT> were resolved at run-time, the compiler would always need to include a check of <FONT FACE="Courier New">AntHill.debug</FONT>韘 value and the body of the <FONT FACE="Courier New">if</FONT> statement just in case value of <FONT FACE="Courier New">AntHill.debug</FONT> ever changed. The value of <FONT FACE="Courier New">AntHill.debug</FONT> can韙 change after it is compiled, of course, because it is declared as final. Still, you could change the source code of <FONT FACE="Courier New">AntHill</FONT> and recompile <FONT FACE="Courier New">AntHill</FONT>, but not recompile <FONT FACE="Courier New">Example2</FONT>.</P>
<P>Because the reference to <FONT FACE="Courier New">AntHill.debug</FONT> is resolved at compile-time the compiler can conditionally compile out the body of the <FONT FACE="Courier New">if</FONT> statement if <FONT FACE="Courier New">AntHill.debug</FONT> is discovered to be <FONT FACE="Courier New">false</FONT>. Note that this means you can韙 change the behavior of the <FONT FACE="Courier New">Example2</FONT> application just be setting <FONT FACE="Courier New">AntHill</FONT> to <FONT FACE="Courier New">false</FONT> and recompiling only <FONT FACE="Courier New">AntHill</FONT>. You have to recompile <FONT FACE="Courier New">Example2</FONT> as well. </P>
<P><FONT FACE="Courier New">Example3</FONT>, shown below, is <FONT FACE="Courier New">Example2</FONT> with its name changed to <FONT FACE="Courier New">Example3</FONT> and compiled with an <FONT FACE="Courier New">AntHill</FONT> that has <FONT FACE="Courier New">debug</FONT> set to <FONT FACE="Courier New">false</FONT>:</P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">// On CD-ROM in file linking/ex3/AntHill.java
<P>class AntHill {</P>
<P>&nbsp;</P>
<P>    static final boolean debug = false;</P>
<P>}</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></P>
<P></FONT><FONT FACE="Courier New">// On CD-ROM in file linking/ex3/Example3.java
<P>class Example3 {</P>
<P>&nbsp;</P>
<P>    public static void main(String[] args) {</P>
<P>        if (AntHill.debug) {</P>
<P>            System.out.println("Debug is true!");</P>
<P>        }</P>
<P>    }</P>
<P>}</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></FONT><FONT FACE="Courier New">end</FONT></P></PRE>
<P>Here are the bytecodes generated by <FONT FACE="Courier New">javac</FONT> for <FONT FACE="Courier New">Example3</FONT>韘 <FONT FACE="Courier New">main()</FONT> method:</P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">0 return     // return void
</FONT><FONT SIZE="2"><P>&nbsp;</P></FONT><FONT FACE="Courier New">end</FONT></P></PRE>
<P>As you can see, the Java compiler has brazenly eliminated the entire <FONT FACE="Courier New">if</FONT> statement found in <FONT FACE="Courier New">Example3.main()</FONT>. There is not even a hint of the <FONT FACE="Courier New">println()</FONT> invocation in this very short bytecode sequence.</P>
<H3><EM><P>Direct References</P>
</EM></H3><P>The ultimate goal of constant pool resolution is to replace a symbolic reference with a direct reference. The form of symbolic references is well-defined in Chapter 6, &quot;The Java Class File,&quot; but what form do direct references take? As you might expect, the form of direct references is yet another decision of the designers of individual Java Virtual Machine implementations. Nevertheless, there are some characteristics likely to be common among most implementations.</P>
<P>Direct references to types, class variables, and class methods are likely native pointers into the method area. A direct reference to a type can simply point to the implementation-specific data structure in the method area that holds the type data. A direct reference to a class variable can point to the class variable韘 value stored in the method area. A direct reference to a class method can point to a data structure in the method area that contains the data needed to invoke the method. For example, the data structure for a class method could include information such as whether or not the method is native. If the method is native, the data structure could include a function pointer to the dynamically linked native method implementation. If the method is not native, the data structure could include the method韘 bytecodes, max_stack, max_locals, and so on. If there is a just-in-time-compiled version of the method, the data structure could include a pointer to that just-in-time-compiled native code.</P>
<P>Direct references to instance variables and instance methods are offsets. A direct reference to an instance variable is likely the offset from the start of the object韘 image to the location of the instance variable. A direct reference to an instance method is likely an offset into a method table.</P>
<P>Using offset to represent direct references to instance variables and instance methods depends on a predictable ordering of the fields in a class韘 object image and the methods in a class韘 method table. Although implementation designers may choose any way of placing instance variables into an object image or methods into a method table, they will almost certainly use the same way for all types. Therefore, in any one implementation, the ordering of fields in an object and methods in a method table is defined and predictable.</P>
<P>As an example, consider this hierarchy of three classes and one interface:</P>
<PRE><P><FONT FACE="Courier New">begin</FONT></P>
<FONT SIZE="2"><P></FONT><FONT FACE="Courier New">// On CD-ROM in file linking/ex4/Friendly.java
<P>interface Friendly {</P>
<P>&nbsp;</P>
<P>    void sayHello();</P>
<P>    void sayGoodbye();</P>
<P>}</P>
</FONT><FONT SIZE="2"><P>&nbsp;</P></P>
<P></FONT><FONT FACE="Courier New">// On CD-ROM in file linking/ex4/Dog.java
<P>class Dog {</P>
<P>&nbsp;</P>
<P>    // How many times this dog wags its tail when</P>
<P>    // saying hello.</P>
<P>    private int wagCount = ((int) (Math.random() * 5.0)) + 1;</P>
<P>&nbsp;</P>
<P>    void sayHello() {</P>
<P>&nbsp;</P>
<P>        System.out.print("Wag");</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -