假设我们需要在本机代码中实现一些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);
我在同一个项目中看到了实际项目中的两种方法,甚至前者和后者。
所以,我的问题是:所提到的任何替代方案是否具有某些技术或性能或可维护性优势,应鼓励仅使用一种变体。或许这只是一个品味问题?
答案 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函数是否需要是本机的,而不仅仅是计算的一部分,而且可以在任何时候再次更改。