2011-01-28 09:53:00 dingxy 阅读数 610
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    58234 人正在学习 去看看 李宁

今天偶然看代码,发现别人有这样写的方法,并且jar里面有几个dll文件,比较奇怪,于是把代码打开,发现如下写法。

  1.     public  native  String GSMModemSMSReadAll(String s, int  i);
  2.     public  native  String GSMModemGetErrorMsg(String s);
  3.     public  native  boolean  GSMModemIsConn(String s);

觉得挺有趣的,找了找网络上的资料,感觉不错。又一个使用java调用别的语言的方法(以前不知道-_#)

 

  今天花了两个小时把一份关于什么是Native Method的英文文章好好了读了一遍,以下是我依据原文的理解。

一. 什么是Native Method
   简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如 在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数。
   "A native method is a Java method whose implementation is provided by non-java code."
   在定义一个native method时,并不提供实现体(有些像定义一个java interface),因为其实现体是由非java语言在外面实现的。,下面给了一个示例:   
    public class IHaveNatives
    {
      native public void Native1( int x ) ;
      native static public long Native2() ;
      native synchronized private float Native3( Object o ) ;
      native void Native4( int[] ary ) throws Exception ;
    }
    这些方法的声明描述了一些非java代码在这些java代码里看起来像什么样子(view).
    标识符native可以与所有其它的java标识符连用,但是abstract除外。 这是合理的,因为native暗示这些方法是有实现体的,只不过这些 实现体是非java的,但是abstract却显然的指明这些方法无实现体。native与其它java标识符连用时,其意义同非Native Method并无差别,比如native static表明这个方法可以在不产生类的实例时直接调用,这非常方便,比如当你想用一个native method去调用一个C的类库时。上面的第三个方法用到了native synchronized,JVM在进入这个方法的实现体之前会执行同步锁机制(就像java的多线程。)
    一个native method方法可以返回任何java类型,包括非基本类型,而且同样可以进行异常控制。这些方法的实现体可以制一个异常并且将其抛出,这一点与java 的方法非常相似。当一个native method接收到一些非基本类型时如Object或一个整型数组时,这个方法可以访问这非些基本型的内部,但是这将使这个native方法依赖于你所访 问的java类的实现。有一点要牢牢记住:我们可以在一个native method的本地实现中访问所有的java特性,但是这要依赖于你所访问的java特性的实现,而且这样做远远不如在java语言中使用那些特性方便和 容易。
    native method的存在并不会对其他类调用这些本地方法产生任何影响,实际上调用这些方法的其他类甚至不知道它所调用的是一个本地方法。JVM将控制调用本地 方法的所有细节。需要注意当我们将一个本地方法声明为final的情况。用java实现的方法体在被编译时可能会因为内联而产生效率上的提升。但是一个 native final方法是否也能获得这样的好处却是值得怀疑的,但是这只是一个代码优化方面的问题,对功能实现没有影响。
    如果一个含有本地方法的类被继承,子类会继承这个本地方法并且可以用java语言重写这个方法(这个似乎看起来有些奇怪),同样的如果一个本地方法被fianl标识,它被继承后不能被重写。
   本地方法非常有用,因为它有效地扩充了jvm.事实上,我们所写的java代码已经用到了本地方法,在sun的java的并发(多线程)的机制实现中,许 多与操作系统的接触点都用到了本地方法,这使得java程序能够超越java运行时的界限。有了本地方法,java程序可以做任何应用层次的任务。


二.为什么要使用Native Method
   java使用起来非常方便,然而有些层次的任务用java实现起来不容易,或者我们对程序的效率很在意时,问题就来了。
   与java环境外交互:
   有时java应用需要与java外面的环境交互。这是本地方法存在的主要原因,你可以想想java需要与一些底层系统如操作系统或某些硬件交换信息时的情 况。本地方法正是这样一种交流机制:它为我们提供了一个非常简洁的接口,而且我们无需去了解java应用之外的繁琐的细节。
   与操作系统交互:
   JVM支持着java语言本身和运行时库,它是java程序赖以生存的平台,它由一个解释器(解释字节码)和一些连接到本地代码的库组成。然而不管怎 样,它毕竟不是一个完整的系统,它经常依赖于一些底层(underneath在下面的)系统的支持。这些底层系统常常是强大的操作系统。通过使用本地方 法,我们得以用java实现了jre的与底层系统的交互,甚至JVM的一些部分就是用C写的,还有,如果我们要使用一些java语言本身没有提供封装的操 作系统的特性时,我们也需要使用本地方法。
    Sun's Java
    Sun的解释器是用C实现的,这使得它能像一些普通的C一样与外部交互。jre大部分是用java实现的,它也通过一些本地方法与外界交互。例如:类 java.lang.Thread 的 setPriority()方法是用java实现的,但是它实现调用的是该类里的本地方法setPriority0()。这个本地方法是用C实现的,并被 植入JVM内部,在Windows 95的平台上,这个本地方法最终将调用Win32 SetPriority() API。这是一个本地方法的具体实现由JVM直接提供,更多的情况是本地方法由外部的动态链接库(external dynamic link library)提供,然后被JVM调用。


三.JVM怎样使Native Method跑起来:
    我们知道,当一个类第一次被使用到时,这个类的字节码会被加载到内存,并且只会回载一次。在这个被加载的字节码的入口维持着一个该类所有方法描述符的 list,这些方法描述符包含这样一些信息:方法代码存于何处,它有哪些参数,方法的描述符(public之类)等等。
    如果一个方法描述符内有native,这个描述符块将有一个指向该方法的实现的指针。这些实现在一些DLL文件内,但是它们会被操作系统加载到java程 序的地址空间。当一个带有本地方法的类被加载时,其相关的DLL并未被加载,因此指向方法实现的指针并不会被设置。当本地方法被调用之前,这些DLL才会 被加载,这是通过调用java.system.loadLibrary()实现的。
  
   最后需要提示的是,使用本地方法是有开销的,它丧失了java的很多好处。如果别无选择,我们可以选择使用本地方法。

2015-11-30 21:25:08 qq_21033663 阅读数 2593
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    58234 人正在学习 去看看 李宁

native修饰符


"A native method is a Java method whose implementation is provided by non-java code."

简单来说一个Native Method就是一个java调用非java代码的接口。

这个也比较好理解,因为java底层本来就是用c、c++去写的,所以当然有对应接口去直接调用C/C++写的方法;而且众所周知java对底层的操作远不如C/C++灵活,所以可以通过直接调用非java代码来实现对底层的操作。在java api中有很多这种方法,例如:

系统提供的数组拷贝方法public static native void arraycopy(Object src,  int  srcPos,Object dest, int destPos,int length);等

2012-05-31 08:12:12 suiusoar 阅读数 430
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    58234 人正在学习 去看看 李宁

---------------------- android培训java培训、期待与您交流! ---------------------

 

JAVA程序中用关键字native 修饰的方法,表明这个方法是用C、C++等非JAVA语言实现!

显然这种方式提高了JAVA程序的运行效率、与操作系统交互、访问旧系统或库

可以将native方法比作Java程序同C等非JAVA语言程序的接口,因此这种方式又叫JNIjava native inerface)JAVA本地调用

 

实现JNI调用的步骤:

Java中声明native()方法,然后编译

javah产生一个.h文件

.c文件实现native导出方法,其中需要包含以上的.h文件(还要包含了JDKjni.h

将第三步的.c文件编译成动态链接库文件(DLLDynamic Link Liberary

Java中用System.loadLibrary()方法加载生成的DLLnative()的C实现即可在JAVA中调用

 

实现JNI调用的步骤(图解):

 

 

代码实现:

public class Testext {

                 public static native void helloWorldInNative(); //此方法用C语言实现

                 static {     System.loadLibrary("test");    } //加载test.dll

                 public static void main(String[] args) {       helloWorldInNative();       }

}

编译Testext.java得到Testext.class

创建Native Method的头文件Testext.h         javah –jni Testext

 

Testext.c文件中实现helloWorldInNative()

#include "Testext.h"

#include "stdio.h"

#include "jni.h" //…JDK\include目录下的三个文件jni.hjawt_md.hjni_md.h复制到VisualC++include目录下

JNIEXPORT void JNICALL Java_Testext_helloWorldInNative (JNIEnv *env, jobject obj)

{    printf("Hello Native World!\n");       return;     }

 

 Testext.c编译生成test.dll

S:\testJNI>cl-I "D:\Soft\Program\JAVA\JDK\include" -I "D:\Soft\Program\JAVA\JDK\include\win32"

-I "D:\Soft\Program\VisualC++\C++\Include" -MD -LD Testext.c -Fetest.dll

 

用java.exe运行程序Testext.class:

      S:\testJNI>java Testext

  Hello Native World!

 

 

 

 

 

 

 

 

----------------------- android培训java培训、期待与您交流! ----------------------

 

 

详细请查看:http://edu.csdn.net/heima

2018-03-16 16:21:10 zyzzxycj 阅读数 1102
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    58234 人正在学习 去看看 李宁

最近开始学习java基础工具等源码,还是得更耐心些,去体会精髓的地方。。


看到了ArrayList.java中的fastRemove方法:




由于数组删除了中间一个元素,就必须把之后的元素向前移动一位。发现这边用的是System.arraycopy:




之后就找不到它的实现源码了。查了native修饰符 才知道:


"A native method is a Java method whose implementation is provided by non-java code."


简单来说一个Native Method就是一个java调用非java代码的接口。


这个也比较好理解,因为java底层本来就是用c、c++去写的,所以当然有对应接口去直接调用C/C++写的方法;而且众所周知java对底层的操作远不如C/C++灵活,所以可以通过直接调用非java代码来实现对底层的操作。在java api中有很多这种方法,例如:


系统提供的数组拷贝方法public static native void arraycopy(Object src,  int  srcPos,Object dest, int destPos,int length);等


暂时看不到源码,就看到网上有人说这个方法的复制,居然是浅复制的!!


所以只能通过做一个测试来验证:


public class testMain {
    public static void main(String[] args) {

        Te[] t1 = new Te[1];
        t1[0] = new Te("a");
        Te[] t2 = new Te[1];
        System.out.println(t1[0]);
        //调用
        System.arraycopy(t1, 0, t2, 0, 1);
        System.out.println(t2[0]);

    }

    static class Te {
        String name;

        Te(String name) {
            this.name = name;
        }
    }
}


从输出中可以看出 指针指向了同一个地址:




然后再进行修改,发现因为指向了同一个地址,t2的值确实跟着一起改变了:


Te[] t1 = new Te[1];
        t1[0] = new Te("a");
        Te[] t2 = new Te[1];
        System.out.println(t1[0]);
        //调用
        System.arraycopy(t1, 0, t2, 0, 1);
        System.out.println(t2[0]);

        System.out.println("t1修改前:"+t1[0].name);
        System.out.println("t2修改前:"+t2[0].name);

        t1[0].name = "1";

        System.out.println("t1修改后:"+t1[0].name);
        System.out.println("t2:"+t2[0].name);




对t1[0]进行修改,但是由于t1[0]和t2[0]引用了同一个对象,因此后者也会随之改变,在平时的使用中如果不注意的话会引起相当大的问题。
 
而且由于System.arraycoppy()是JDK中的native方法,JDK中有关于集合,数组操作的基本上都调用此方法,因此在使用这些的时候要注意。

2017-12-01 14:20:12 qq_29463709 阅读数 1457
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    58234 人正在学习 去看看 李宁
native主要用于方法上:

1、一个native方法就是一个Java调用非Java代码的接口。一个native方法是指该方法的实现由非Java语言实现,比如用C或C++实现。
2、在定义一个native方法时,并不提供实现体(比较像定义一个Java Interface),因为其实现体是由非Java语言在外面实现的。

说明:
  Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。
  JNI是Java本机接口(Java Native Interface),是一个本机编程接口,它是Java软件开发工具箱(Java Software Development Kit,SDK)的一部分。JNI允许Java代码使用以其他语言编写的代码和代码库。Invocation API(JNI的一部分)可以用来将Java虚拟机(JVM)嵌入到本机应用程序中,从而允许程序员从本机代码内部调用Java代码。

举例:
  在JDK源码中,以system.class为例,由于调用操作系统的相关方法,而操作的实现并不是用Java,所以就会有很多native修饰的方法

JAVA native关键字

阅读数 2163

没有更多推荐了,返回首页