Java本机方法。公共与私人

时间:2017-01-04 23:10:30

标签: java java-native-interface

假设我们需要在本机代码中实现一些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);
    

我在同一个项目中看到了实际项目中的两种方法,甚至前者和后者。

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

2 个答案:

答案 0 :(得分:4)

  

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

可维护性优势是关键所在。如评论中所述,该对象暴露其行为。如何实施不是用户的业务。这为您提供了更大的灵活性。

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

至于性能,从理论上讲,第一种方法更快,因为它减少了1次。在实践中,它完全可以忽略不计。

答案 1 :(得分:2)

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

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() { } } 相同:

# User credentials.
# Permissions to create tables, indices and triggers must be granted to JDBC user.
# The schema must be created first.
sonar.jdbc.username=sonarqube
sonar.jdbc.password=password
#----- Embedded Database (default)
# H2 embedded database server listening port, defaults to 9092
# sonar.embeddedDatabase.port=9092
#----- MySQL 5.6 or greater
# Only InnoDB storage engine is supported (not myISAM).
# Only the bundled driver is supported. It can not be changed.
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false

这意味着您可以在不影响用户的任何时间点将实现更改为本机,纯java,纯Java包装到本机私有方法。可能存在一个问题,即整个公共API函数是否需要是本机的,而不仅仅是计算的一部分,而且可以在任何时候再次更改。