Java中的native,transient,volatile和strictfp关键字

本文详细解释了Java中的四个关键字:native、transient、volatile和strictfp的功能及使用场景。包括native方法如何与本地代码交互,transient如何控制序列化过程,volatile确保多线程环境下变量的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java中的native,transient,volatile和strictfp关键字

Java中的native,transient,volatile和strictfp关键字

博客分类: J2SEJavaJ#JNI VC ++Fortran写道1,native是方法修饰符。Native方法是由另外一种语言(如c/c++,FORTRAN,汇编)实现的本地方法。一般用于JNI中。 

public class testdll 

static 

System.loadLibrary("test"); 


public native static int get(); 

public native static void set(int i); 

public static void main(String[] args) 

testdll test = new testdll(); 
test.set(10); 
System.out.println(test.get()); 



test.dll可以用VC写,例如, 
-----testdll.h----- 
/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class testdll */ 

#ifndef _Included_testdll 
#define _Included_testdll 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class: testdll 
* Method: get 
* Signature: ()I 
*/ 
JNIE XP ORT jint JNICALL Java_testdll_get 
(JNIEnv *, jclass); 

/* 
* Class: testdll 
* Method: set 
* Signature: (I)V 
*/ 
JNIEXPORT void JNICALL Java_testdll_set 
(JNIEnv *, jclass, jint); 

#ifdef __cplusplus 

#endif 
#endif 


-------testdll.c----------- 
#include "testdll.h" 

int i = 0; 

JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass) 

return i; 


JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j) 

i = j; 
}写道2,transient 

transient是一个变量修饰符,标记为transient的变量,在对一个对象进行序列化时,这些变量状态不会被序列化。 

例如,假设某个类的成员变量是transient,那么当通过ObjectOutputStream把这个类的某个实例保存到磁盘上时,实际上transient变量的值是不会保存的。 

当对象序列化的保存在存储器上时,不希望有些字段 数据 被保存,为了保证安全性,可以把这些字段声明为transient。 

要更明白,可以看一些序列化的内容。

 

写道3,volatile 
优快云 有一篇介绍过,现贴回来。 

volatile修饰变量。在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。 
看看Java Language Specification中的例子。 
条件:一个线程不停的调用方法one(),一个线程不停的调用方法two()。我测试过多次,这种情况好像一直没有出现。 

代码 
class Test { 
static int i = 0, j = 0; 
static void one() { i++; j++; } 
static void two() { 
System.out.println("i=" + i + " j=" + j); 



结果偶尔会出现j大于i的情况,因为方法没有同步,所以会出现i和j可能不是一次更新。一种防止这种情况发生的办法就是声明两个方法为synchronized 的。 

代码 
class Test { 
static int i = 0, j = 0; 
static synchronized void one() { i++; j++; } 
static synchronized void two() { 
System.out.println("i=" + i + " j=" + j); 



这样可以防止两个方法同时被执行,还可以保证j和i被同时更新,这样一来i和j的值一直是一样的。 
另外一种途径就是把i和j声明为volatile。 

代码 
class Test { 
static volatile int i = 0, j = 0; 
static void one() { i++; j++; } 
static void two() { 
System.out.println("i=" + i + " j=" + j); 

}
<think>好的,我需要回答用户关于Java中不能修饰接口的关键字的问题。首先,我应该回顾一下Java接口的基本概念常见的关键字修饰符。 首先,接口在Java中是使用`interface`关键字声明的,默认情况下它们是抽象的,只能包含抽象方法(在Java 8之前)。从Java 8开始,接口可以有默认方法静态方法。用户想知道哪些关键字不能用来修饰接口。 接下来,我需要列出可以修饰接口的关键字,然后排除它们,剩下的就是不能修饰的关键字。常见的修饰符有`public`、`abstract`、`strictfp`等。例如,接口默认是抽象的,所以显式使用`abstract`是允许的,但不是必须的。`public`接口可以在任何包中访问,而默认(无修饰符)的接口则只能在同一个包内访问。 然后,我需要考虑那些不能修饰接口的关键字。比如,`final`关键字不能修饰接口,因为接口本身需要被其他类实现,如果接口是final的,就无法被继承或实现,这与接口的设计目的相悖。同样,`static`也不能用于顶层接口,虽然内部接口可以是静态的。另外,`private``protected`也不能修饰顶层接口,因为它们涉及访问控制,而顶层接口只能是public或包私有。还有`transient`、`volatile`、`synchronized`这些通常用于变量的关键字,显然不适用于接口。`native``strictfp`可能也需要确认,但记得`strictfp`在Java中是可以修饰接口的,用于限制浮点计算的精度。 可能需要进一步验证某些关键字是否真的不能修饰接口。例如,`final`确实不允许修饰接口,尝试写`final interface MyInterface`会导致编译错误。同样,`private interface`在顶层是不允许的,但在内部类中可能允许,但用户的问题可能指的是顶层接口。 总结一下,不能修饰接口的关键字包括`final`、`static`(顶层)、`private`(顶层)、`protected`、`transient`、`volatile`、`synchronized`、`native`等。需要逐个检查这些关键字是否适用,并给出例子解释,确保答案准确。</think>在Java中,接口(`interface`)的修饰符有一定限制,以下是**不能修饰接口的关键字**及其原因分析: --- ### 1. **`final`** - **原因**:接口的设计目的是被其他类实现或扩展,若用`final`修饰,则禁止继承或实现,违背接口的核心作用。 - **示例**: ```java final interface MyInterface {} // 编译错误:Illegal combination of modifiers ``` --- ### 2. **`static`(用于顶层接口)** - **原因**:`static`只能修饰嵌套接口(内部接口),表示其不依赖外部类实例。但**顶层接口**(直接定义在类外的接口)不能用`static`修饰。 - **示例**: ```java class Outer { static interface NestedInterface {} // 允许:嵌套静态接口 } static interface TopLevelInterface {} // 编译错误:Illegal modifier ``` --- ### 3. **`private`(用于顶层接口)** - **原因**:顶层接口的访问权限只能是`public`或默认(包私有)。`private`仅可用于嵌套接口,限制其仅在外围类内访问。 - **示例**: ```java class Outer { private interface InnerInterface {} // 允许:私有嵌套接口 } private interface MyInterface {} // 编译错误:Illegal modifier ``` --- ### 4. **`protected`** - **原因**:`protected`表示“仅子类或同包类可访问”,但接口无法通过继承层级控制访问,因此不支持此修饰符。 - **示例**: ```java protected interface MyInterface {} // 编译错误:Illegal modifier ``` --- ### 5. **`transient` / `volatile` / `synchronized`** - **原因**: - `transient`:用于标记序列化时忽略的字段,接口不包含字段的具体实现。 - `volatile`:用于多线程变量可见性,接口中不能定义实例变量。 - `synchronized`:用于方法同步,接口方法默认是抽象的,无具体实现。 - **示例**: ```java interface MyInterface { transient int x; // 编译错误:接口字段默认是public static final volatile int y; // 同上 synchronized void foo();// 编译错误:抽象方法不能用synchronized } ``` --- ### 6. **`native`** - **原因**:`native`用于标记用其他语言(如C/C++)实现的方法,但接口方法只能是抽象或默认实现,无法绑定到本地代码。 - **示例**: ```java interface MyInterface { native void bar(); // 编译错误:接口方法不能是native } ``` --- ### ✅ **允许修饰接口的关键字** - `public`:公开访问(默认包私有)。 - `abstract`:接口默认隐式抽象,显式声明冗余但合法。 - `strictfp`:从Java 2开始允许,限制接口内浮点运算的精度。 --- ### 总结表格 | 不可用关键字 | 原因 | |-------------------|----------------------------------------------------------------------| | `final` | 接口需被实现或继承 | | `static`(顶层) | 仅嵌套接口可用 | | `private`(顶层) | 仅嵌套接口可用 | | `protected` | 接口无继承层级访问控制 | | `transient` | 接口字段默认是`public static final`,无需序列化控制 | | `volatile` | 同上 | | `synchronized` | 接口方法无具体实现 | | `native` | 接口方法无法绑定本地代码 | 若需进一步验证,可通过编写简单代码并观察编译错误确认。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值