gpt4 book ai didi

java - 为什么 SIZE 常量仅适用于 Integer 和 Long 的 @Native?

转载 作者:IT老高 更新时间:2023-10-28 20:41:36 28 4
gpt4 key购买 nike

我了解 @Native 的使用注释。

Indicates that a field defining a constant value may be referenced from native code. The annotation may be used as a hint by tools that generate native header files to determine whether a header file is required, and if so, what declarations it should contain.

但是,在阅读 java 源代码时,我注意到在类 IntegerLong 中,SIZE 常量是 @Native 而不是 Float、Byte、Double、Short 和 Character。

请注意,SIZE 常量表示用于表示实际值的位数。

public static final int SIZE = 8;//Byte
public static final int SIZE = 16;//Character
public static final int SIZE = 16;//Short
public static final int SIZE = 32;//Float
@Native public static final int SIZE = 32;//Integer
@Native public static final int SIZE = 64;//Long
public static final int SIZE = 64;//Double

编辑:我刚刚注意到这也适用于同一类的 MAX_VALUEMIN_VALUE


编辑 2: 我有空闲时间对此进行了一些研究,并查看了 Long、Float 等类的头文件,我希望找出常量不存在在其他标题中,但不幸的是它们是。

static const jint SIZE = 8L;//java/lang/Byte.h
static const jint SIZE = 16L;//java/lang/Character.h
static const jint SIZE = 16L;//java/lang/Short.h
static const jint SIZE = 32L;//java/lang/Float.h
static const jint SIZE = 32L;//java/lang/Integer.h
static const jint SIZE = 64L;//java/lang/Double.h
static const jint SIZE = 64L;//java/lang/Long.h

为什么 SIZE 常量只有 @Native for Integer 和 Long ?

最佳答案

TLDR:跳到结论


Why is the SIZE constant only @Native for Integer and Long?

@Native 的简史

我在邮件列表上进行了一些搜索。我发现了一些有趣的东西。

起初注释(1 2) javax.tools.annotation.ForceNativeHeader 被介绍到

to trigger javah on a class.

它被 com.sun.tools.javac.processing.NativeapiVisitor 使用.通过查看代码我们可以看到,如果类声明了一些本地方法或者类被注释@ForceNativeHeader,就会生成本地头。 .

后来此注释已重命名为 GenerateNativeHeader (12)。

那么 this annotation was added to several types (尤其是 IntegerLong )带有有趣的评论:

/* No native methods here, but the constants are needed in the supporting JNI code */
@GenerateNativeHeader
public final class Long extends Number implements Comparable<Long> {...

但是通过添加这个注释它添加a problematic dependency从基本模块到包含 javax.tools 的模块。因此注释从 Integer 中删除。和 Long 这些文件是明确的added to the build process因为不再自动生成标题... "(hopefully temporary) hack" .

所以新注释java.lang.annotation.Native was created并用于IntegerLong .注释被设置为 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.


这些东西的全部目的是:

javac could generate native headers for classes containing native methods.

Integer的情况和 Long

这是 JEP 139: Enhance javac to Improve Build Speed 的一部分:

javah will be automatically run on any class that contains native methods and the generated C-headers will be put in the (-h) headerdir. A new annotation @ForceNativeHeader is used for classes that have final static primitives that need to be exported to JNI, but no native methods.


基本实验

我在 JDK 上做了一个基本的实验。我克隆了 open-jdk 森林,并成功构建了它。正如所料,为 Integer 生成的头文件和 Long (感谢 @Native )和 FloatDouble (感谢他们的原生方法)但不适用于 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
...

然后我尝试删除 @Native来自 Integer字段,我尝试再次构建 jdk但我得到一个错误:

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.

从逻辑上讲,因为标题尚未生成。

我也确认了java_lang_Integer.h包含在几个 c 和 cpp 文件中:

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

喜欢 Long

find .  \( -name "*.c" -o -name "*.cpp" \) -exec grep "java_lang_Long.h" {} \; -print
#include "java_lang_Long.h"
./jdk/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c

喜欢 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

和喜欢 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

但两者都不是Short

find .  \( -name "*.c" -o -name "*.cpp" \) -exec grep "java_lang_Short.h" {} \; -print

也不是 Byte , 也不是 Character .


结论

在所有这些类型中,只有 Integer , Long , Float , Doublejdk的原生源代码中使用。

只有 IntegerLong字段用 @Native 注释 因为它们没有本地方法(相对于 FloatDouble)

关于java - 为什么 SIZE 常量仅适用于 Integer 和 Long 的 @Native?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28770822/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com