Java 中的为什么SIZE仅为整数和长整数@Native?

简介: Java 中的为什么SIZE仅为整数和长整数@Native?

我了解注释的用法。

指示可以引用定义常量值的字段

来自本机代码。注释可被以下工具用作提示:

生成本机头文件以确定头文件是否

必需的,如果是,它应该包含什么声明。

然而,在阅读Java源代码时,我注意到在类@NativeInteger中,Long常量是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

编辑:我刚注意到这也适用于同一类的@NativeMAX_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

编辑:我刚注意到这也适用于同一类的@NativeMAX_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

为什么只有@native的整型和长型的大小常量?

最佳答案

TLDR:跳到结论

为什么只有@native的整型和长型的大小常量?

@Native

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

一开始是注释(12javax.tools.annotation.ForceNativeHeader

被介绍给

在类上触发javah。

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

后来,此注释被重命名为@ForceNativeHeader12)。

然后(尤其是this annotation was added to several typesInteger)带有一个相互关联的注释:

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


但是通过添加这个注释,它可以将基础模块中的Long添加到包含javax.tools的模块中。因此注释从a problematic dependencyGenerateNativeHeader中删除,并且这些文件显式地Integer了,因为不再自动生成标题…Aadded to the build process

因此,一个新的注释用于"(hopefully temporary) hack"was created。注释被设置为Long

注释应该直接应用于需要导出的常量字段,而不是整个类。

这些东西的目的是:

javac可以为包含本机方法的类生成本机头。

这是java.lang.annotation.NativeTargetType FIELD

这是Integer的一部分:

javah将自动在包含本机方法的任何类上运行,生成的c-headerdir将放在(-h)headerdir中。新的注释@forceNativeHeader用于具有最终静态原语的类,这些原语需要导出到JNI,但没有本地方法。

基础实验

我在JDK上做了一个基本的实验。我克隆了开放的JDK林,并成功地构建了它。正如预期的那样,为IntegerLong生成的头文件(多亏了Integer)和Long生成的头文件(多亏了它们的本地方法),但不是为@NativeFloat生成的头文件。


    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
    ...

然后我尝试从Double字段中删除Byte并尝试再次构建Short但得到一个错误:

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.

逻辑上,因为没有生成头。
我还确认了@Native包含在多个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

逻辑上,因为没有生成头。

我还确认了@Native包含在多个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

喜欢Integer

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

喜欢jdk

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

就像java_lang_Integer.h

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

但两者都不是Long

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

也不是Float,也不是Double
结论
在所有这些类型中,JDK的本机源代码中只使用了ShortByteCharacterInteger
而且只有LongFloat字段被注释为Double,因为它们没有本地方法(与IntegerLong相反)

 

本文翻译自https://stackoverflow.com/questions/28770822/

目录
相关文章
|
1月前
|
Java
Java中整数(负数)的二进制表示
Java中整数(负数)的二进制表示
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 13. 罗马数字转整数 详细解读
[Java·算法·简单] LeetCode 13. 罗马数字转整数 详细解读
23 0
|
1月前
|
算法 Java 开发者
Java:求正整数分解为质因数Java
Java:求正整数分解为质因数Java
|
1月前
|
算法 Java C++
【Java】深入理解Java中的Native关键字
【Java】深入理解Java中的Native关键字
45 0
|
1月前
|
存储 Java 计算机视觉
|
1月前
|
Java
Java 中表示整数的包装类Integer(详解)
Java 中表示整数的包装类Integer(详解)
|
2月前
|
Java
Java字符串转整数的超简单方法!
Java字符串转整数的超简单方法!
32 0
|
2月前
|
Java
LeetCode-整数转罗马数字=Java
整数转罗马数字=Java题解
12 0
|
2月前
|
Java 测试技术
java字符串练习题5、罗马数字转整数
java字符串练习题5、罗马数字转整数
25 0
|
2月前
|
Java Linux iOS开发
8 种 Java- 内存溢出之五 -Unable to create new native thread
8 种 Java- 内存溢出之五 -Unable to create new native thread