Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java本机方法。公共与私人_Java_Java Native Interface - Fatal编程技术网

Java本机方法。公共与私人

Java本机方法。公共与私人,java,java-native-interface,Java,Java Native Interface,假设我们需要在本机代码中实现一些java方法,并将其公开给用户。我们知道所有的工作都是由本机端完成的,也就是说,java代码的唯一职责是将用户提供的参数传递给本机代码并返回结果。据此,java层可以通过两种方式实现: 通过使用直接向用户公开的本机方法: public native Object doSmth(Object arg0, Object arg1); 通过使用围绕私有本机方法的精简公共包装器: public Object doSmth(Object arg0, Object ar

假设我们需要在本机代码中实现一些java方法,并将其公开给用户。我们知道所有的工作都是由本机端完成的,也就是说,java代码的唯一职责是将用户提供的参数传递给本机代码并返回结果。据此,java层可以通过两种方式实现:

  • 通过使用直接向用户公开的本机方法:

    public native Object doSmth(Object arg0, Object arg1);
    
  • 通过使用围绕私有本机方法的精简公共包装器:

    public Object doSmth(Object arg0, Object arg1) {
        return nativeDoSmth(arg0, arg1);
    }
    
    private native Object nativeDoSmth(Object arg0, Object arg1);
    
我在实际项目中看到了这两种方法,甚至在同一项目中看到了前者和后者


所以,我的问题是:提到的任何替代方案是否有一些技术或性能或可维护性优势,这应该鼓励只使用一种变体。或者也许这只是一个品味的问题

我认为这主要是个人风格的选择。如果考虑以下代码:

rattias macbookpro:tst rattias$diff Test1.cl Test1.class rattias macbookpro:tst rattias$vi Test1.java

public class Test1 {
  public static void main(String[] args) {
    Test2 t = new Test2();
    t.m();
  }
}

public class Test2 {
  public native void m();
}
编译它会生成一个
Test1.class
,它与
Test2
定义如下时生成的类相同:

public class Test2 {
  public void m() {
  }
}  
这意味着您可以随时将实现更改为本机纯java,将纯java包装更改为本机私有方法,而不会影响用户。可能存在这样一个问题:整个公共API函数是否需要是本机函数,而不仅仅是计算的一部分,但这一点在任何时候都可以更改

所以,我的问题是:上述任何一种替代方案都有一些优点吗 技术或性能或可维护性优势,应 鼓励只使用一种变体

可维护性优势是这里的关键。如注释中所述,对象公开其行为。它的实现方式与用户无关。这给了你更多的灵活性

假设将来(请参阅:维修性)您发现您希望/需要调整该方法,使其在本机调用之前和/或之后执行某些操作。在第一种方法中,您需要弃用该方法并创建一个新方法。在第二种方法中,您只需在方法中添加所需的内容,而用户并不关心


至于性能,理论上,第一种方法更快,因为它减少了1次调用。实际上,这完全可以忽略不计

public
方法是objects API的一部分。
native
方法是一种实现决策。实现细节不应该对公共API可见。选项2对API隐藏了实现。您会发现选项2专用于JDK,而不是选项1。我认为这是一个好主意,它在设计和维护JNI层时为您提供了另一个自由度。通常情况并非如此,因为对于类的API来说,在JNI代码中需要做大量的工作。在许多情况下,使用Java将输入和输出转换为更易于在JNI中使用的数据类型更为简单。无需反对该方法,因为您可以简单地从第一个变量更改为第二个变量,而无需任何客户端代码注意。因此,在真正需要第二个之前,没有必要使用第二个。当然,这需要重新编译本机代码,但这应该由您控制。@Holger我不明白。在第一种方法中,您希望在本机代码中进行更改吗?如果使用第二种方法,您在Java端也会做同样的更改?不。当需要在Java端修饰方法时,您可以将变体1更改为变体2,从而获得第二种变体的所有好处。由于
本机
方法的名称在两种变体中不同,因此需要调整本机代码的名称,或者创建具有新名称的委托。在这两种情况下,本机代码都需要重新编译,但不会有明显的更改。