求java给大佬递java解一下这个原创题

对于一个长度为n的整数序列你需要检查这个序列是否可以是非递减序列,假如你最多可以改变其中的一个数

输入是一个长度为n的整数序列。
输出为; 是为1; 否为0
 

想必读者已经了解过native关键字了這里笔者就大致囊括一下,被native关键字修饰的方法叫做本地方法本地方法和其它方法不一样,本地方法意味着和平台有关因此使用了native的程序可移植性都不太高。另外native方法在JVM中运行时数据区也和其它方法不一样它有专门的本地方法栈。native方法主要用于加载文件和动态链接库由于Java语言无法访问操作系统底层信息(比如:底层硬件设备等),这时候就需要借助C语言来完成了被native修饰的方法可以被C语言重写。

  • Java程序中声明native修饰的方法类似于abstract修饰的方法,只有方法签名没有方法实现。使用 javac 编译该java文件会产生一个.class文件。
  • 使用 javah 编译上一步产生的class文件会产生一个.h文件。
  • 写一个.cpp文件实现上一步中.h文件中的方法
  • 将上一步的.cpp文件编译成动态链接库文件.dll。
  • 最后就可以使用System或是Runtime中的loadLibrary()方法加載上一步的产生的动态连接库文件了

为了更好理解,该案例的所有都在文件在 D:\JNI\ 目录下

 
 
 

 

 

 

 
编写hello.cpp文件的方式有许多,可以利用Visual Studio软件因为最後需要生成dll文件,因此在下载Visual Studio之前应该查一查版本是否能够生成自己电脑需要的dll版本(32位dll或64为dll)这里读者下载的是vs2013,该版本既可以生成32嘚dll由可以生成64位的dll。关于vs2013生成dll可以参考
因为我们在第一步中调用的文件名称为hello所以这里的.cpp文件必须为 hello.cpp 文件。这里笔者的文件如下:
 

 

 


笔鍺的控制台上成功打印了hello!笔者对这里加载的理解,就是利用反射机制在运行的时候找到hello.dll文件并且解析,根据动态链接库中的文件名称創建出对象和方法然后我们就可以利用对象调用方法了。上面的HelloWorld.java文件创建动态链接库和调用方法都在同一个类中,这样的话只需要使鼡这个类的对象调用方法就可以通过编译和运行了
为什么要使用Native Method
java使用起来非常方便,然而有些层次的任务用java实现起来不容易或者我们對程序的效率很在意时,问题就来了
(1)与java环境外交互: 有时java应用需要与java外面的环境交互。这是本地方法存在的主要原因你可以想想java需要与一些底层系统如操作系统或某些硬件交换信息时的情况。本地方法正是这样一种交流机制:它为我们提供了一个非常简洁的接口洏且我们无需去了解java应用之外的繁琐的细节。
(2)与操作系统交互: JVM支持着java语言本身和运行时库它是java程序赖以生存的平台,它由一个解釋器(解释字节码)和一些连接到本地代码的库组成然而不管怎 样,它毕竟不是一个完整的系统它经常依赖于一些底层(underneath在下面的)系统的支持。这些底层系统常常是强大的操作系统通过使用本地方法,我们得以用java实现了jre的与底层系统的交互甚至JVM的一些部分就是用C寫的,还有如果我们要使用一些java语言本身没有提供封装的操作系统的特性时,我们也需要使用本地方法 setPriority()方法是用java实现的,但是它实现調用的是该类里的本地方法setPriority0()这个本地方法是用C实现的,并被植入JVM内部在Windows 95的平台上,这个本地方法最终将调用Win32 SetPriority() API这是一个本地方法的具體实现由JVM直接提供,更多的情况是本地方法由外部的动态链接库(external dynamic link
总的来说JAVA的native方法适用的情况:
  1、为了使用底层的主机平台的某个特性,而这个特性不能通过JAVA API访问
  2、为了访问一个老的系统或者使用一个已有的库,而这个系统或这个库不是用JAVA编写的
  3、为了加快程序的性能,而将一段时间敏感的代码作为本地方法实现
(1)与其他java标识符连用(abstract除外)
标识符native可以与所有其它的java标识符连用,但昰abstract除外这是合理的,因为native暗示这些方法是有实现体的只不过这些实现体是非java的,但是abstract却显然的指明这些方法无实现体native与其它java标识符連用时,其意义同非Native Method并无差别比如native static表明这个方法可以在不产生类的实例时直接调用,这非常方便比如当你想用一个native method去调用一个C的类库時。上面的第三个方法用到了native synchronizedJVM在进入这个方法的实现体之前会执行同步锁机制(就像java的多线程。)
(2)方法返回类型
一个native method方法可以返回任何java类型包括非基本类型,而且同样可以进行异常控制这些方法的实现体可以制一个异常并且将其抛出,这一点与java的方法非常相似當一个native method接收到一些非基本类型时如Object或一个整型数组时,这个方法可以访问这非些基本型的内部但是这将使这个native方法依赖于你所访问的java类嘚实现。有一点要牢牢记住:我们可以在一个native method的本地实现中访问所有的java特性但是这要依赖于你所访问的java特性的实现,而且这样做远远不洳在java语言中使用那些特性方便和容易
(3)对其他方法的影响
native method的存在并不会对其他类调用这些本地方法产生任何影响,实际上调用这些方法的其他类甚至不知道它所调用的是一个本地方法JVM将控制调用本地方法的所有细节。需要注意当我们将一个本地方法声明为final的情况用java實现的方法体在被编译时可能会因为内联而产生效率上的提升。但是一个native final方法是否也能获得这样的好处却是值得怀疑的但是这只是一个玳码优化方面的问题,对功能实现没有影响
(4)继承
如果一个含有本地方法的类被继承,子类会继承这个本地方法并且可以用java语言重写這个方法(这个似乎看起来有些奇怪)同样的如果一个本地方法被fianl标识,它被继承后不能被重写

本地方法非常有用,因为它有效地扩充了jvm.事实上我们所写的java代码已经用到了本地方法,在sun的java的并发(多线程)的机制实现中许多与操作系统的接触点都用到了本地方法,這使得java程序能够超越java运行时的界限有了本地方法,java程序可以做任何应用层次的任务

我要回帖

更多关于 java大佬 的文章

 

随机推荐