TL; DR : transition to conclusion
Why is the SIZE constant only @Native for integers and longs?
A Brief History of @Native
I did a few searches on the mailing lists. I found interesting things.
First, annotation ( 1 2 ) javax.tools.annotation.ForceNativeHeader was introduced in
to call javah for the class.
Used by com.sun.tools.javac.processing.NativeapiVisitor . Looking at the code, we see that a custom header is generated if the class declares some of its own methods or the class is annotated by @ForceNativeHeader .
This annotation was later renamed GenerateNativeHeader ( 1 2 ).
This annotation is then added to several types (especially Integer and Long ) with an interesting comment:
@GenerateNativeHeader public final class Long extends Number implements Comparable<Long> {...
But by adding this annotation, add the problematic dependency on the base module to the module containing javax.tools. Thus, the annotation was removed from Integer and Long , and these files were explicitly added to the build process , since the header is no longer generated automatically ... a "(hopefully temporary) hack" .
So a new annotation java.lang.annotation.Native was created and used in Integer and Long . Annotations were set as TargetType FIELD .
the annotation should be directly applied to the constant fields that need to be exported, and not to the class as a whole.
This whole goal is as follows:
javac can generate custom headers for classes that contain custom methods.
This is the case of Integer and Long
this was part of JEP 139: Enhance javac to improve build speed :
javah will automatically run in any class that contains its own methods, and the generated C-headers will be placed in the (-h) headerdir. The new @ForceNativeHeader annotation is used for classes with finite static primitives that need to be exported to JNI, but not using native methods.
Core experimentation
I conducted basic experiments on the JDK. I am cloning an open-jdk forest and I am successfully creating it. As expected, the header files generated for Integer and Long (thanks to @Native ) and for Float and Double (thanks to their own methods), but not for Byte , Short ..
ls -l build/macosx-x86_64-normal-server-release/support/headers/java.base/java_lang_* ... java_lang_Double.h java_lang_Float.h java_lang_Integer.h java_lang_Long.h java_lang_Object.h java_lang_Package.h ...
Then I tried to remove @Native from the Integer fields, and I tried to create jdk again, but I get an error:
jdk/src/java.base/unix/native/libnio/ch/FileChannelImpl.c:35:10: fatal error: 'java_lang_Integer.h' file not found #include "java_lang_Integer.h" ^ 1 error generated.
logically, since the header was not generated.
I also confirmed that java_lang_Integer.h included in several c and cpp files :
find . \( -name "*.c" -o -name "*.cpp" \) -exec grep "java_lang_Integer.h" {} \; -print #include "java_lang_Integer.h" ./jdk/src/java.base/unix/native/libnio/ch/FileChannelImpl.c #include "java_lang_Integer.h" ./jdk/src/java.base/unix/native/libnio/ch/IOUtil.c #include "java_lang_Integer.h" ./jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c #include "java_lang_Integer.h" ./jdk/src/java.base/windows/native/libnio/ch/FileChannelImpl.c #include <java_lang_Integer.h> ./jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp
like Long
find . \( -name "*.c" -o -name "*.cpp" \) -exec grep "java_lang_Long.h" {} \; -print
like Float
find . \( -name "*.c" -o -name "*.cpp" \) -exec grep "java_lang_Float.h" {} \; -print #include "java_lang_Float.h" ./jdk/src/java.base/share/native/libjava/Float.c #include "java_lang_Float.h" ./jdk/src/java.base/share/native/libjava/ObjectInputStream.c #include "java_lang_Float.h" ./jdk/src/java.base/share/native/libjava/ObjectOutputStream.c
and like Double
find . \( -name "*.c" -o -name "*.cpp" \) -exec grep "java_lang_Double.h" {} \; -print #include "java_lang_Double.h" ./jdk/src/java.base/share/native/libjava/Double.c #include "java_lang_Double.h" ./jdk/src/java.base/share/native/libjava/ObjectInputStream.c #include "java_lang_Double.h" ./jdk/src/java.base/share/native/libjava/ObjectOutputStream.c
but not Short
find . \( -name "*.c" -o -name "*.cpp" \) -exec grep "java_lang_Short.h" {} \; -print
and Byte , not Character .
Conclusion
Among all these types, only Integer , Long , Float , Double are used in the source code for jdk .
And only Integer and Long tags are annotated using @Native , as they have no built-in methods (unlike Float and Double )