@native 是 java 8 引入的普通注解(非元注解),定义在 java.lang 包中,用于标记 public static final 基本类型或 string 常量字段,供本地代码生成工具导出为 c/c++ 宏,仅保留于源码阶段。

Native 在 Java 元注解中并不存在,也不是元注解(如 @Target、@Retention、@Documented、@Repeatable)的组成部分。它既不是注解类型,也不在 java.lang.annotation 包中定义。因此,“元注解中的 @Native” 是一个常见误解——@Native 并非元注解,而是一个**普通注解**,且自 Java 8 起被引入,用于标记**常量字段(static final 基本类型或 String 字段)**,向生成本地代码(如 JNI 头文件)的工具表明该字段值应被导出为 C/C++ 层可见的宏或常量。
Native 注解的真实定位与用途
@Native 定义在 java.lang 包中(java.lang.Native),属于 JDK 内部工具链协作机制的一部分,而非开发者日常使用的语义注解。它的核心作用是:
- 标识某个
public static final基本类型(如int、long)或String字段,其值需被javah(已废弃)或现代替代方案(如jextract或构建脚本中的头文件生成器)提取为本地头文件中的#define或const声明; - 不改变 JVM 运行时行为,无反射可见性(
@Retention(RetentionPolicy.SOURCE)),仅保留在源码阶段; - 典型用于 JDK 自身类库(如
java.io.File中的pathSeparator、separator),以便本地实现层统一引用同一常量值。
为什么它常被误认为“元注解”?
误解多源于两点:
- 名称含 “Native”,易与
native方法关键字混淆,进而联想为底层机制相关的“元级”注解; - 它出现在 JDK 源码的常量字段上(如
java.nio.channels.spi.SelectorProvider中的PROVIDER_CLASS),位置类似元注解使用场景,但实际只是普通注解的应用实例。
在常量字段中使用的具体规则
要使 @Native 发挥预期作用,必须满足以下条件:
- 只能标注
public static final字段; - 字段类型限于基本类型(
byte、short、int、long、char、boolean)、String,或枚举常量(但实践中极少用于枚举); - 字段必须有编译期常量值(即字面量或编译期可确定的表达式,如
1 ); - 注解本身不可继承(
@Inherited不适用),且无运行时保留策略——工具仅在编译或源码分析阶段读取。
实际效果与工具依赖性
@Native 本身不产生任何运行时或编译期强制约束。它的语义完全由外部工具解释:
- 旧版
javah -jni会扫描带@Native的字段并生成对应 C 宏; - 现代构建中,需配合自定义注解处理器或脚本(如基于
javax.annotation.processing)提取这些字段; - 若无相应工具链支持,添加
@Native对程序功能、性能、反射行为均无任何影响。
@Native 是一个面向本地互操作的源码标记,专注常量导出,与元注解无关,也不参与注解处理流程。理解它,关键在于区分“谁读取它”和“它控制什么”——答案是:只有特定工具读它,它不控制任何 Java 行为。









