java中是否有内联函数的概念,或者它取代了其他东西?如果有,它是如何使用的?我听说public
,static
和final
方法是内联函数。我们可以创建自己的内联函数吗?
8 回答
在 Java 中,优化通常在 JVM 级别完成。在运行时,JVM 执行一些“复杂”的分析来确定要内联的方法。它可以积极内联,Hotspot JVM 实际上可以内联非最终方法。
java 编译器几乎从不内联任何方法调用(JVM 在运行时完成所有这些)。他们做内联编译时间常数(例如最终的静态原始值)。但不是方法。
如需更多资源:
Wiki:OpenJDK 中的内联,未完全填充,但包含指向有用讨论的链接。
不,java中没有内联函数。是的,当放置在公共类中时,您可以在代码中的任何地方使用公共静态方法。java 编译器可以对静态或最终方法进行内联扩展,但这不能保证。
通常,此类代码优化是由编译器结合 JVM/JIT/HotSpot 对经常使用的代码段进行的。此外,其他优化概念,如参数的寄存器声明,在 java 中也是未知的。
优化不能通过 java 中的声明来强制,而是由编译器和 JIT 完成。在许多其他语言中,这些声明通常只是编译器提示(您可以声明比处理器更多的寄存器参数,其余的被忽略)。
声明 java 方法 static、final 或 private 也是编译器的提示。你应该使用它,但没有保证。Java 性能是动态的,而不是静态的。由于类加载,第一次调用系统总是很慢。下一个调用更快,但取决于内存和运行时,最常见的调用在运行系统内进行了优化,因此服务器在运行时可能会变得更快!
Java 没有提供手动建议应该内联方法的方法。正如@notnoop 在评论中所说,内联通常由 JVM 在执行时完成。
你上面说的是对的。有时 final 方法被创建为内联,但没有其他方法可以在 java 中显式创建内联函数。
好吧,在java中有一些方法可以称为“内联”方法,但取决于jvm。编译后,如果方法的机器码小于35字节,则立即转入内联方法,如果方法的机器码小于325字节,则可以转入内联方法,具体取决于jvm。
现实生活中的例子:
public class Control {
public static final long EXPIRED_ON = 1386082988202l;
public static final boolean isExpired() {
return (System.currentTimeMillis() > EXPIRED_ON);
}
}
然后在其他类中,如果代码已过期,我可以退出。如果我从另一个类引用 EXPIRED_ON 变量,则该常量内联到字节码,因此很难追踪代码中检查到期日期的所有位置。但是,如果其他类调用 isExpired() 方法,则调用实际方法,这意味着黑客可以用另一个总是返回 false 的方法替换 isExpired 方法。
我同意强制编译器将静态最终方法内联到所有引用它的类会非常好。在这种情况下,您甚至不需要包含 Control 类,因为在运行时不需要它。
根据我的研究,这是无法做到的。也许一些混淆器工具可以做到这一点,或者,您可以修改构建过程以在编译之前编辑源代码。
至于证明在编译期间是否将控制类中的方法内联到另一个类中,请尝试在类路径中不包含控制类的情况下运行另一个类。
Java9 有一个“提前”编译器,它在编译时而不是运行时进行多项优化,这可以看作是内联的。
所以,似乎没有,但是您可以使用 guava 或等效的 Function 类实现来使用此解决方法,因为该类非常简单,例如:
assert false : new com.google.common.base.Function<Void,String>(){
@Override public String apply(Void input) {
//your complex code go here
return "weird message";
}}.apply(null);
是的,这是死代码,只是为了举例说明如何创建一个复杂的代码块(在 {} 内)来做一些如此具体的事情,不应该打扰我们为它创建任何方法,AKA 内联!