web-dev-qa-db-ja.com

javacパラメータフラグの欠点

実行時にパラメーターの名前を必要とするいくつかのフレームワーク機能を試したいので、アプリを-parametersでコンパイルする必要があり、パラメーターの名前がJVMバイトコードに格納されます。

このパラメーターの使用には、jar/warのサイズ以外にどのような欠点がありますか?

15
VladS

クラスファイル形式へのパラメータ名の追加は、 JEP 118 でカバーされています。これはJava 8で提供されました。なぜ含めるのかについて少し議論がありました。 OpenJDKの電子メールスレッドでパラメータ名がオプションになりました ここ および ここ 。簡単に言うと、パラメータ名をオプションにする理由は、クラスファイルのサイズ、互換性の表面、および機密情報。

互換性の表面の問題は、いくつかの追加の議論に値します。上にリンクされているスレッドの1つは、パラメーター名の変更はバイナリ互換の変更であると述べています。これは真実ですが、JVMのバイナリ互換性の概念の厳密なコンテキストでのみです。つまり、メソッドのパラメーター名を変更しても、そのメソッドをJVMでリンクできるかどうかは変わりません。しかし、この声明は一般的に互換性には当てはまりません。

歴史的に、パラメータ名はローカル変数名のように扱われてきました。 (結局のところ、それらはスコープ内でローカルです。)自由に変更でき、メソッド以外には何も影響しません。しかし、パラメータ名へのリフレクティブアクセスを有効にすると、プログラムの他の部分がそれを使用している可能性があることを考えずに、突然名前を変更できなくなります。さらに悪いことに、パラメーター名のすべての使用に対して厳密なテストケースがあるか、これらのケースを見つけることができる本当に優れた静的アナライザーがない限り、何もわかりません(私は1つを知りません)。

コメントは、メソッドのパラメーター名をJSONプロパティ名にマップする機能を持つJackson(JSON処理ライブラリ)の使用に関する質問にリンクされています。これは非常に便利かもしれませんが、パラメーター名を変更すると、JSONバインディングが壊れることもあります。さらに悪いことに、プログラムがJavaメソッドパラメータ名に基づいてJSON構造を生成している場合、メソッドパラメータ名を変更すると、データ形式またはワイヤプロトコルがサイレントに変更される可能性があります。明らかに、このような環境では、これを使用します機能は確実に、非常に優れたテストを行う必要があることを意味します。さらに、どのパラメーター名を変更してはならないかを示すコメントがコードの周りに散らばっています。

19
Stuart Marks

onlyは、バイトコードに詳細情報が含まれるようになるため、変更される.classのサイズです。

public class DeleteMe3 {
    public static void main(String[] args) {
    }

    private static void go(String s) {
    }
}

たとえば、これには次のようなパラメータ名に関する情報が含まれます。

private static void go(Java.lang.String);
   descriptor: (Ljava/lang/String;)V
   flags: ACC_PRIVATE, ACC_STATIC
   Code:
     stack=0, locals=1, args_size=1
       0: return
     LineNumberTable:
       line 11: 0
   MethodParameters:
     Name                           Flags
     s

このMethodParametersは、-parametersなしでは存在しません。

これでうまく機能しないフレームワークがあるかもしれません。これが1つです Spring Data JPA Issue 。しばらく前にヒットしてアップグレードしなければならなかったので、私はそれについて知っています(私はそれ以降他の人に直面していません)。

2
Eugene