After reading the appropriate JLS section, there is nothing in JLS that prohibits the use of static and native in the method definition. According to the relevant JVM specification:
Method-level synchronization is performed implicitly as part of a method call and return (§2.11.8). The synchronized method is highlighted in the pool constant structure of the continuous process pool (§4.6) by the flag ACC_SYNCHRONIZED, which is checked by the method invocation instructions. When a method is called for which ACC_SYNCHRONIZED is set, the executable thread enters the monitor, calls the method itself, and exits the monitor whether the method call completes normally or abruptly. While the execution thread is running, the monitor belongs; no other thread can enter it. If an exception is thrown when the synchronized method is called, and the synchronized method does not handle the exception, the monitor for the method automatically exits to the exception from the synchronized method.
Because of this, the generated bytecode does not have any monitorenter or monitorexit , as the synchronized block does. The only thing generated in this case is invokestatic to invoke the static method. This command is generated if you call the static native synchronized method, the static native method, or the static method.
Here is an example of the code with the generated bytecode:
public static void main( String[] args ){ doSomething1(); System.out.println("Now do 2"); doSomething2(); System.out.println("native java"); doSomethingJava(); String s = "test"; synchronized ( s ){ int x = 9 + 5; } } public static native void doSomething1(); public static synchronized native void doSomething2(); public static synchronized void doSomethingJava(){ System.out.println("synchronized"); }
Generated Byte Code:
Compiled from "test.java" class test { test(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: invokestatic #2 // Method doSomething1:()V 3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 6: ldc #4 // String Now do 2 8: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 11: invokestatic #6 // Method doSomething2:()V 14: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 17: ldc #7 // String native java 19: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 22: invokestatic #8 // Method doSomethingJava:()V 25: ldc #9 // String test 27: astore_1 28: aload_1 29: dup 30: astore_2 31: monitorenter 32: bipush 14 34: istore_3 35: aload_2 36: monitorexit 37: goto 47 40: astore 4 42: aload_2 43: monitorexit 44: aload 4 46: athrow 47: return Exception table: from to target type 32 37 40 any 40 44 40 any public static native void doSomething1(); public static synchronized native void doSomething2(); public static synchronized void doSomethingJava(); Code: 0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #10 // String synchronized 5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return }
source share