- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我了解 @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 源代码时,我注意到在类 Integer
和 Long
中,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_VALUE
和 MIN_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 (尤其是 Integer 和 Long )带有有趣的评论:
/* 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并用于Integer和 Long .注释被设置为 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
)和 Float
和 Double
(感谢他们的原生方法)但不适用于 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
, Double
在jdk的原生源代码中使用。
只有 Integer
和 Long
字段用 @Native
注释 因为它们没有本地方法(相对于 Float
和 Double
)
关于java - 为什么 SIZE 常量仅适用于 Integer 和 Long 的 @Native?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28770822/
我找到了long int long和 int long long可以编译为变量类型。 long int long有什么区别吗, int long long , long long和 long long
我无法找出为什么“加密”函数仍然将“消息”读取为字符串,尽管我已经使用不同的方法将数据类型更改为字节。 错误消息是“Prince 类型中的方法 Encrypt(long, long, long, lo
这个问题在这里已经有了答案: Is "long long" = "long long int" = "long int long" = "int long long"? (4 个答案) 关闭 6 年
我正在从 Java 过渡到 C++,并且对 long 数据类型有一些疑问。在 Java 中,要保存大于 232 的整数,您只需编写 long x;。但是,在 C++ 中,long 似乎既是数据类型又是
clang-tidy 12.0.1 报告了一个相当奇怪的警告。在以下代码中: #include int main() { std::vector v1; const auto a =
我创建了一个 pair 和 long long int 的映射 - map,long long int >; 和一个交互器 - map, long long int >::iterator it1;
我想知道 unsigned long long 和 unsigned long long int 的主要区别。它们可以互换使用吗? 对于像 9223372036854775807 这样的大十进制数的计
我看到的大多数代码都使用缩写类型来声明变量,例如 long long x; // long long int x short y; // short int y 我浏览了 C++11 标准(第 3.9
common_type::type是 unsigned long因为关于积分提升后的操作数,标准说... [...] if the operand that has unsigned integer
long long int A = 3289168178315264; long long int B = 1470960727228416; double D = sqrt(5); long lon
这些新数据类型的目的是什么?我通常只使用“int”或“long”,但为什么会存在这些呢?它们带来了什么新功能或用途? 最佳答案 long int一直是long的全称,只是很少用而已。 long lon
我正在运行以下for循环 for(unsigned long long int i = N-1; i >= 0; i--){ cin>>L[i]; } 当程序到达这个代码段时,它停止响应。但是
最近问了一个关于递归导致这个问题的问题 注意-> count() 函数返回键 K 在 map 容器中出现的次数。如果键存在于容器中,则返回 1,因为映射仅包含唯一键。如果 map 容器中不存在键,则返
好的,所以我正在尝试实现客户端 - 服务器程序(套接字编程)。 我的客户发送一个嵌入字符串中的 long long int,如下所示: char copy[10]; sprintf(send_data
如果我有任务 Long c = a + b; 有没有一种简单的方法来检查 a + b 不大于/小于 Long.MAX_VALUE/Long.MIN_VALUE? 最佳答案 使用 Guava , 就这么
我需要制作一个 Comparator 来根据它的 long 类型的变量之一对我的对象列表进行排序。 public class ParticipantIndexComparator implements
假设我有这两种类型: typedef unsigned long long uint64; typedef signed long long sint64; 我有这些变量: uint64 a = ..
long long 和 long 有什么区别?而且它们都不适用于 12 位数字 (600851475143),我是不是忘记了什么? #include using namespace std; int
当结果将大于 C 中的 long long int 时,是否有可能对两个不同的 long long int 变量求和? 最佳答案 由于 OP 想要“在屏幕上打印结果”,因此将数字分成两部分:Most-
实际上我必须找到从源顶点到所有其他顶点的最短路径。为此,我获得了下面给出的代码模板。我想实现“Bellman–Ford algorithm”。 #include #include #include
我是一名优秀的程序员,十分优秀!