- 浏览: 150272 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
EclipseEye:
fair_jm 写道不错 蛮详细的 谢谢分享
SWT/JFace专题 --- SWT中Display和多线程 -
fair_jm:
不错 蛮详细的 谢谢分享
SWT/JFace专题 --- SWT中Display和多线程
以java中java.lang.System类中的一个得到系统当前时间的native方法为例,对native关键字进行说明:
__________________________________________________________
public final class System {//final关键字修饰的类不能被继承
.......
/**
*返回系统当前时间(该方法依赖于底层操作系统的实现)
*/
public static native long currentTimeMillis();
.......
}
__________________________________________________________
对于上面的currentTimeMillis();声明为native 表明:该方法的具体实现是依赖于底层的操作系统平台,并非java语言实现。
所以,一个native方法就是java调用非java代码的接口,当在方法中调用一些不是由java语言写的代码或者在方法中用java语言
直接操纵计算机硬件时要声明为native方法。native 方法中除了不能和abstract关键字连用(abstract表示方法是空实现,这显然与native调用外部实现的事实不符),非native方法并无区别。
---
JAVA本地方法适用的情况
1.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问
2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的
3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。
----------------------------------------
类首次被使用到时,编译生成字节码会被加载到内存。在该字节码的入口维持着一个该类所有方法描述符的列表,这些方法描述符包含了类的详细信息。对应native方法,描述符块中会有一个指向该方法的实现的指针。这些实现在一些DLL文件(动态链接库文件dll是由java类编译后的.h文件及jni.h文件信息和具体的方法实现等编译生成的)内,当native方法被调用时,java会调用System.loadLibrary(*.dll)方法加载该dll。
其中,java通过javah(Javah:产生可以调用Java过程的C过程,或建立能被Java程序调用的C过程的头文件)生成该类的.h文件。
jni(Java Native Interface,java本地接口)
------------------------------------------下面是加载dll文件的具体实现-------
另外,java.lang.System还用到了java中的另外两个比较常见的关键字:final和static。
在这里也做简单的说明:
关于final:
final修饰的类(比如System)表示该类不可被继承,所以final不能修饰interface或abstract类;
final修饰的方法不能被子类覆盖(不能被Override),不能修饰构造函数;
final修饰字段属性、参数时表示其被第一次赋值后不能被修改(但这里请注意,如果是一个对象,
不能修改的是该对象的引用,但是对象的内容还是可以修改的)
使用final的 好处:
1.防止被修改;2.final类型的方法被调用时,编译器会把它嵌入进来在一定程度上会提高了编译效率(注意是:一定程度,原因如下)。
编译器有一种被称为inline的机制,它会使你在调用final方法时,直接将方法主体插入到调用处,而不是进行例行的方法调用,例如保存断点,压栈等,这样可能会使你的程序效率有所提高,然而当你的方法主体非常庞大时,或你在多处调用此方法,那么你的调用主体代码便会迅速膨胀,可能反而会影响效率,所以你要慎用final进行方法定义。
---------
关于static:
static 可以理解为“类”级别的关键字,因此对于static不存在this的概念,当类被jvm加载时,会按照声明的先后对static成员字段进行初始化
于是,static 可用于定义全局变量,而 static final 就可以定义一个常量
__________________________________________________________
public final class System {//final关键字修饰的类不能被继承
.......
/**
*返回系统当前时间(该方法依赖于底层操作系统的实现)
*/
public static native long currentTimeMillis();
.......
}
__________________________________________________________
对于上面的currentTimeMillis();声明为native 表明:该方法的具体实现是依赖于底层的操作系统平台,并非java语言实现。
所以,一个native方法就是java调用非java代码的接口,当在方法中调用一些不是由java语言写的代码或者在方法中用java语言
直接操纵计算机硬件时要声明为native方法。native 方法中除了不能和abstract关键字连用(abstract表示方法是空实现,这显然与native调用外部实现的事实不符),非native方法并无区别。
---
JAVA本地方法适用的情况
1.为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问
2.为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的
3.为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现。
----------------------------------------
类首次被使用到时,编译生成字节码会被加载到内存。在该字节码的入口维持着一个该类所有方法描述符的列表,这些方法描述符包含了类的详细信息。对应native方法,描述符块中会有一个指向该方法的实现的指针。这些实现在一些DLL文件(动态链接库文件dll是由java类编译后的.h文件及jni.h文件信息和具体的方法实现等编译生成的)内,当native方法被调用时,java会调用System.loadLibrary(*.dll)方法加载该dll。
其中,java通过javah(Javah:产生可以调用Java过程的C过程,或建立能被Java程序调用的C过程的头文件)生成该类的.h文件。
jni(Java Native Interface,java本地接口)
------------------------------------------下面是加载dll文件的具体实现-------
/** *java.lang.System中, 加载由 libname 参数指定的系统库 */ public static void loadLibrary(String libname) {//调用Runtime的loadLibrary方法 Runtime.getRuntime().loadLibrary0(getCallerClass(), libname); } /** *Runtime的loadLibrary方法(带有synchronized的同步方法) */ synchronized void loadLibrary0(Class fromClass, String libname) { //用于判断libname所指定文件的合法性 SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkLink(libname); } if (libname.indexOf((int)File.separatorChar) != -1) { throw new UnsatisfiedLinkError( "Directory separator should not appear in library name: " + libname); } //调用ClassLoader的loadLibrary方法 ClassLoader.loadLibrary(fromClass, libname, false); } /** *ClassLoader的loadLibrary方法 */ // Invoked in the java.lang.Runtime class to implement load and loadLibrary. static void loadLibrary(Class fromClass, String name, boolean isAbsolute) { try { if (!DownloadManager.isJREComplete() && !DownloadManager.isCurrentThreadDownloading()) { DownloadManager.downloadFile("bin/" + System.mapLibraryName(name)); } } catch (Exception e) { throw new UnsatisfiedLinkError("Error downloading library " + name + ": " + e); } ClassLoader loader = (fromClass == null) ? null : fromClass.getClassLoader(); if (sys_paths == null) { usr_paths = initializePath("java.library.path"); sys_paths = initializePath("sun.boot.library.path"); } } ....... }--------------------------------------------------------------------------------------------------------------------------------
另外,java.lang.System还用到了java中的另外两个比较常见的关键字:final和static。
在这里也做简单的说明:
关于final:
final修饰的类(比如System)表示该类不可被继承,所以final不能修饰interface或abstract类;
final修饰的方法不能被子类覆盖(不能被Override),不能修饰构造函数;
final修饰字段属性、参数时表示其被第一次赋值后不能被修改(但这里请注意,如果是一个对象,
不能修改的是该对象的引用,但是对象的内容还是可以修改的)
使用final的 好处:
1.防止被修改;2.final类型的方法被调用时,编译器会把它嵌入进来在一定程度上会提高了编译效率(注意是:一定程度,原因如下)。
编译器有一种被称为inline的机制,它会使你在调用final方法时,直接将方法主体插入到调用处,而不是进行例行的方法调用,例如保存断点,压栈等,这样可能会使你的程序效率有所提高,然而当你的方法主体非常庞大时,或你在多处调用此方法,那么你的调用主体代码便会迅速膨胀,可能反而会影响效率,所以你要慎用final进行方法定义。
---------
关于static:
static 可以理解为“类”级别的关键字,因此对于static不存在this的概念,当类被jvm加载时,会按照声明的先后对static成员字段进行初始化
于是,static 可用于定义全局变量,而 static final 就可以定义一个常量
发表评论
-
Nio Socket
2013-05-16 05:53 0asfda -
结合jdk源码解读,Error Exception
2013-05-10 04:00 0/* * @(#)Error.java 1.17 05/11 ... -
从不同的角度,重新审视class和interface
2013-05-07 03:40 0java开发中,对应class和interface的基本区别都 ... -
java.lang.Object
2013-05-07 03:35 0/* * @(#)Object.java 1.73 06/0 ... -
反射机制+类加载机制
2013-02-18 01:30 0反射机制+类加载机制 -
并发专题----使用开源软件Amino构建并发应用程序/多线程运行时分析工具MTRAT
2013-02-14 00:50 1377使用开源软件构建并发 ... -
并发专题 ---- 线程安全
2013-02-14 00:50 753线程安全 ================== ... -
并发专题 --- 锁
2013-02-14 00:50 806相比于synchronized,ReentrantLock 提 ... -
并发专题 ----(JMM)java内存模型
2013-02-14 00:50 542Java 内存模型 ------------ ... -
并发专题 ---java.util.concurrent 包
2013-02-13 02:26 1840java.util.concurrent 包 原 ... -
集合框架 Queue篇(8)---PriorityBlockingQueue、SynchronousQueue
2013-02-07 12:40 1317Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(7)---LinkedBlockingDeque
2013-02-07 12:40 853Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(6)---LinkedBlockingQueue
2013-02-07 12:39 835Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(5)---ArrayBlockingQueue
2013-02-06 10:39 706Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(4)---阻塞队列和生产者-消费者模式、DelayQueue
2013-02-06 10:39 998Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(3)---ConcurrentLinkedQueue
2013-02-06 10:38 1050Queue ------------ 1.ArrayDequ ... -
集合框架 Queue篇(2)---PriorityQueue
2013-02-06 10:38 835Queue ------------ 1.ArrayDeq ... -
集合框架 Queue篇(1)---ArrayDeque
2013-02-06 10:38 932Queue ------------ 1.ArrayDeq ... -
集合框架 Set篇---HashSet、LinkedHashSet、TreeSet、CopyOnWriteArraySet、ConcurrentSkipList
2013-02-05 08:43 1484Set --------- 1.HashSet 2.Link ... -
集合框架 List篇(2)---CopyOnWriteArrayList
2013-02-05 08:43 843List ----------- 1.ArrayList(jd ...
相关推荐
5. **本地到Java的调用**:除了Java调用本地代码,本地代码也可以调用Java的方法。通过`JNIEnv`指针,我们可以获取到Java对象和方法ID,进而调用Java代码。 6. **JNI数据类型映射**:JNI提供了Java数据类型和C数据...
- 首先,需要在Java源代码中使用`native`关键字声明本地方法,例如: ```java public class HelloWorld { native void sayHello(); static { System.loadLibrary("hello"); // 加载动态链接库 } } ``` - ...
在Java类中,使用native关键字声明本地方法。该声明告知JVM该方法将在本地库中实现,因此编译器不会为其生成字节码。例如,声明一个名为foo的本地方法: public native void foo(int x, String y); 3.编译Java类 ...
- **Java调用本地方法**:通过`native`方法的实例方法调用本地代码。 - **本地代码调用Java方法**:通过JNIEnv指针,本地代码可以访问和调用Java对象的方法,访问Java数组,甚至创建新的Java对象。 6. **JNI数据...
- 用于引用超类的关键字,可以调用超类的构造函数或方法。 43. **switch** - 控制流程关键字,用于基于不同情况执行不同的代码块。 44. **synchronized** - 用于同步代码块或方法的关键字,确保线程安全。 ...
Java源文件中定义了需要在native层实现的方法,这些方法通过`native`关键字标记。C/C++源文件则实现这些方法,并通过JNI接口与Java代码交互。JNI头文件是由`javah`工具自动生成,包含了C/C++函数的声明,这些函数与...
在Java编程语言中,有时我们需要调用C或C++编写的原生代码,这通常涉及到Java的本地接口(JNI,Java Native Interface)。JNI允许Java代码与本地代码进行交互,为Java应用程序提供了更广泛的性能和功能扩展。本篇...
在Java源代码中,一个方法声明为`native`关键字表明该方法的实现是在本地代码中,而非Java源代码。例如: ```java public class NativeDemo { public native void callNative(); static { System.loadLibrary(...
Java中的`native`关键字是用来声明一个方法为原生方法,这意味着该方法的实现不在Java代码中,而是由非Java语言(如C或C++)在本地代码中提供。原生方法是Java与操作系统或其他底层系统资源进行直接交互的重要手段,...
在Java中,定义本地方法使用`native`关键字。例如,在`Demo.java`文件中,我们可能会看到类似以下的代码: ```java public class Demo { public native void callNative(); static { System.loadLibrary("demo")...
在Java程序中,要调用本地方法,首先需要在Java类中声明该方法,并使用`native`关键字来标记。例如,在本例中,`Main`类中声明了一个名为`printMessage`的native方法: ```java public class Main { static { ...
本地方法的声明使用`native`关键字,例如: ```java public class NativeDemo { public native void callCFunction(); static { System.loadLibrary("native-lib"); } } ``` `System.loadLibrary()` 方法...
- `native`:声明本地方法。 - `new`:创建新对象。 - `null`:表示空引用。 - `package`:声明包。 - `private`:访问控制修饰符,仅限于当前类内部。 - `protected`:访问控制修饰符,可以被同一包内或子类访问。 ...
- 在Java类中声明`native`关键字修饰的函数,这些函数将在JNI头文件中生成对应的方法声明。 - 加载本地库:使用`System.loadLibrary`加载之前生成的DLL(Windows)或SO(Linux)库。 - 实例化Java类并调用本地...
1. 定义本地方法签名:在Java类中声明native关键字修饰的方法,并使用`{native void methodName(int arg);}`这样的形式定义其签名。 2. 编译头文件:使用`javah`工具,根据Java类中声明的native方法生成对应的C/C++...
总结,C++库封装JNI接口实现Java调用C++涉及的主要步骤包括:声明Java中的本地方法,生成JNI头文件,编写C++实现,编译成库,最后在Java中加载并调用。这个过程需要理解Java和C++之间的数据类型转换,以及如何在两种...
- **native**:用于声明一个方法是由本地代码实现的,而不是Java代码。 #### O系列关键字 - **operator**:同样是一个保留关键字,但在Java中并未实际使用。 #### P系列关键字 - **package**:用于声明类所在的...
这个压缩包的源码可能会包含各种示例,例如如何从Java调用本地方法,如何传递参数,以及如何处理返回值等。通过学习和实践这些示例,开发者可以更深入地理解JNI的工作原理,并能熟练地在Java项目中集成本地代码。
4. **加载库和调用函数**:在Java中,使用`System.loadLibrary("库名")`加载动态链接库,然后通过`native`关键字声明的本地方法调用库中的函数。 例如,`java jni调用so中的函数api.txt`中可能包含了具体的JNI函数...
初次遇见 native是在 java.lang.Object 源码中的一个hashCode方法: public native int hashCode(); 为什么有个native呢?这是我所要学习的地方。所以下面想要总结下native。 一、认识 native 即 JNI,Java...