Javaにインライン関数の概念がありますか、それとも他のものに置き換わっていますか?ある場合、それはどのように使用されますか?と聞いたことがありますがpublic
、メソッドはインライン関数です。独自のインライン関数を作成できますか?static
final
8 に答える
Java では、通常、最適化は JVM レベルで行われます。実行時に、JVM は「複雑な」分析を実行して、インライン化するメソッドを決定します。積極的にインライン化することができ、Hotspot JVM は実際には非 final メソッドをインライン化できます。
Java コンパイラは、メソッド呼び出しをインライン化することはほとんどありません (JVM は実行時にすべて実行します)。それらはインラインコンパイル時定数を行います(例えば、最終的な静的プリミティブ値)。しかし、メソッドではありません。
その他のリソース:
Wiki: Inlining in OpenJDK。完全には入力されていませんが、有用なディスカッションへのリンクが含まれています。
いいえ、Javaにはインライン関数はありません。はい、パブリッククラスに配置すると、コード内のどこでもパブリック静的メソッドを使用できます。Javaコンパイラは、静的メソッドまたはfinalメソッドでインライン展開を行う場合がありますが、それは保証されていません。
通常、このようなコードの最適化は、非常に頻繁に使用されるコードセグメントに対して、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() メソッドを呼び出すと、実際のメソッドが呼び出されます。つまり、ハッカーは isExpired メソッドを、常に false を返す別のメソッドに置き換えることができます。
私は、コンパイラが static final メソッドをそれを参照するすべてのクラスにインライン化することを強制することは非常に良いことに同意します。その場合、実行時には必要ないため、Control クラスを含める必要さえありません。
私の調査によると、これはできません。おそらく、一部の難読化ツールでこれを行うことができます。または、ビルド プロセスを変更して、コンパイル前にソースを編集することもできます。
コントロール クラスのメソッドがコンパイル中に別のクラスにインラインで配置されているかどうかを証明するには、クラスパスに Control クラスを指定せずに他のクラスを実行してみてください。