java中是否有内联函数?

时间:2010-01-19 19:23:01

标签: java inline-code

在java中是否有内联函数的概念,或者它取代了其他内容?如果有,它是如何使用的?我听说publicstaticfinal方法是内联函数。我们可以创建自己的内联函数吗?

8 个答案:

答案 0 :(得分:116)

在Java中,优化通常在JVM级别完成。在运行时,JVM执行一些“复杂”分析以确定要内联的方法。它可以在内联方面具有攻击性,而Hotspot JVM实际上可以内联非最终方法。

java编译器几乎从不内联任何方法调用(JVM在运行时完成所有这些操作)。它们内联编译时间常数(例如最终的静态原始值)。但不是方法。

了解更多资源:

  1. Article: The Java HotSpot Performance Engine: Method Inlining Example

  2. Wiki: Inlining in OpenJDK,未完全填充,但包含有用讨论的链接。

答案 1 :(得分:14)

Java没有提供手动建议应该内联方法的方法。正如@notnoop在评论中所说,内联通常由JVM在执行时完成。

答案 2 :(得分:12)

不,java中没有inline function。是的,当放置在公共类中时,您可以在代码中的任何位置使用公共静态方法。对于静态或最终方法,java编译器可能会inline expansion,但这不能保证。

通常,这些代码优化由编译器结合JVM / JIT / HotSpot完成,以便经常使用代码段。其他优化概念,如参数的寄存器声明,在java中也是未知的。

优化不能通过java中的声明来强制,而是由编译器和JIT完成。在许多其他语言中,这些声明通常只是编译器提示(您可以声明比处理器更多的寄存器参数,其余部分将被忽略)。

声明java方法static,final或private也是编译器的提示。你应该使用它,但没有保证。 Java性能是动态的,而不是静态的。由于类加载,对系统的第一次调用总是很慢。下一次调用更快,但根据内存和运行时,最常见的调用在运行系统中进行了优化,因此服务器在运行时可能会变得更快!

答案 3 :(得分:4)

你上面说的是正确的。有时最终方法是以内联方式创建的,但没有其他方法可以在java中显式创建内联函数。

答案 4 :(得分:2)

现实生活中的例子:

public class Control {
    public static final long EXPIRED_ON = 1386082988202l;
    public static final boolean isExpired() {
        return (System.currentTimeMillis() > EXPIRED_ON);
    }
}

然后在其他类中,如果代码已过期,我可以退出。如果我从另一个类引用EXPIRED_ON变量,则常量内联到字节代码,这使得很难跟踪代码中检查到期日期的所有位置。但是,如果其他类调用isExpired()方法,则调用实际方法,这意味着黑客可以将isExpired方法替换为另一个始终返回false的方法。

我同意强制编译器将静态final方法内联到引用它的所有类是非常好的。在这种情况下,您甚至不需要包含Control类,因为它在运行时不需要。

从我的研究来看,这是不可能做到的。也许一些Obfuscator工具可以做到这一点,或者,您可以修改构建过程以在编译之前编辑源。

至于证明在编译期间来自控件类的方法是否内联到另一个类,尝试在类路径中运行没有Control类的另一个类。

答案 5 :(得分:2)

嗯,有些方法可以在java中称为“内联”方法,但取决于jvm。编译后,如果方法的机器代码小于35字节,它将立即转移到内联方法,如果方法的机器代码小于325字节,它可以转换为内联方法,具体取决于jvm。

答案 6 :(得分:0)

所以,似乎没有,但是您可以使用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内联!

答案 7 :(得分:0)

Java9有一个“Ahead of time”编译器,可以在编译时进行多次优化,而不是运行时,可以看作是内联。