ホームページ  >  記事  >  Java  >  Java 改良章 (14) -----キーワード最終

Java 改良章 (14) -----キーワード最終

黄舟
黄舟オリジナル
2017-02-10 11:28:141124ブラウズ

プログラミングでは、特定のデータを変更できないようにしたい場合があります。このとき、final が機能します。 Final は Java のキーワードで、「この部分は変更できません」を意味します。変更されたくない理由は 2 つあります。それは効率とデザインです。 Final が使用される状況は、データ、メソッド、クラスの 3 つです。


1. 最終データ

データを一定に保つと、運用中のシステムへの負担を軽減できる場合があります。これらの定数データを「定数」と呼ぶことができます。 「定数」は主に次の 2 つの場所で使用されます:

1. コンパイル時の定数は変更できません。

2. 実行時に初期化する場合は、変更されないことを願っています。

​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​: クラスのロードプロセス中に初期化されているため、クラスのロードが完了したときに変更することはできません。コンパイル時にそれを使用する計算式に代入できます。これは、コンパイル時に計算を実行できることを意味します。もちろん、コンパイル時定数の場合は基本型のみを使用でき、定義時に初期化する必要があります。

一部の変数は、オブジェクトごとに異なる動作をさせたいが、同時に変更されたくない場合は、ランタイム定数を使用できます。実行時定数の場合、基本データ型または参照データ型のいずれかになります。基本データ型について不変なのはその内容ですが、参照データ型について不変なのはその参照であり、参照によって指定されるオブジェクトの内容は変更可能です。

public class Person {
    private String name;

    Person(String name){
        this.name = name;
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

public class FinalTest {
    private final String final_01 = "chenssy";    //编译期常量,必须要进行初始化,且不可更改
    private final String final_02;                //构造器常量,在实例化一个对象时被初始化
    
    private static Random random = new Random();
    private final int final_03 = random.nextInt(50);    //使用随机数来进行初始化
    
    //引用
    public final Person final_04 = new Person("chen_ssy");    //final指向引用数据类型
    
    FinalTest(String final_02){
        this.final_02 = final_02;
    }
    
    public String toString(){
        return "final_01 = " + final_01 +"   final_02 = " + final_02 + "   final_03 = " + final_03 +
               "   final_04 = " + final_04.getName();
    }
    
    public static void main(String[] args) {
        System.out.println("------------第一次创建对象------------");
        FinalTest final1 = new FinalTest("cm");
        System.out.println(final1);
        System.out.println("------------第二次创建对象------------");
        FinalTest final2 = new FinalTest("zj");
        System.out.println(final2);
        System.out.println("------------修改引用对象--------------");
        final2.final_04.setName("chenssy");
        System.out.println(final2);
    }
}

------------------
Output:
------------第一次创建对象------------
final_01 = chenssy   final_02 = cm   final_03 = 34   final_04 = chen_ssy
------------第二次创建对象------------
final_01 = chenssy   final_02 = zj   final_03 = 46   final_04 = chen_ssy
------------修改引用对象--------------
final_01 = chenssy   final_02 = zj   final_03 = 46   final_04 = chenssy




ここで説明する唯一のポイントは、一部のデータは最終的なものであるため、コンパイル時に知ることができるとは考えないでください。ここでは、final_03 を通じてそれを知っています。乱数で初期化され、その値は実行時までわかりません。

​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​最終的な方法でその変更を行います。 2 番目の理由である効率については、この効率の問題があまり明確に理解できません。インターネットから次の文章を抜粋しました。 Java の初期の実装では、メソッドを Final として指定すると、コンパイラがそれに同意したことになります。メソッドへのすべての呼び出しがインライン呼び出しに変換されます。コンパイラーは、最後のメソッド呼び出しコマンドを見つけると、独自の慎重な判断により、プログラム コードを挿入する通常の呼び出しメソッドをスキップし、メソッド呼び出しメカニズムを実行します (パラメーターをスタックにプッシュし、実行するメソッド コードにジャンプし、その後、戻ってスタック上のパラメータをクリーンアップし、戻り値を処理し、メソッド呼び出しをメソッド本体内の実際のコードのコピーに置き換えます。これにより、メソッド呼び出しのオーバーヘッドがなくなります。もちろん、メソッドが大きい場合、プログラム コードが肥大化し、メソッド内で費やされる時間の分だけパフォーマンスの向上が減少するため、インライン化によるパフォーマンスの向上が見られない可能性があります。

この文章はよくわからないので、Java の専門家が説明してくれるのでコピーしました。 !

親クラスの最終メソッドをサブクラスでオーバーライドすることはできません。つまり、サブクラスが親クラスと同じメソッドを持つことはできません。

public class Custom extends Person{
    public void method1(){
        System.out.println("Person's  method1....");
    }
    
//    Cannot override the final method from person:子类不能覆盖父类的final方法
//    public void method2(){
//        System.out.println("Person's method2...");
//    }
}

3. Final クラス

クラスが Final で変更されている場合、それはそのクラスが最終クラスであり、他のクラスがそのクラスを継承することを望まないか、または継承を許可しないことを示します。プログラミングでは、安全性またはその他の理由から、このクラスへの変更は許可されていません。また、現時点では、final を使用してクラスを変更できます。

对于final修饰的类来说,它的成员变量可以为final,也可以为非final。如果定义为final,那么final数据的规则同样适合它。而它的方法则会自动的加上final,因为final类是无法被继承,所以这个是默认的。

       四、 final参数

       在实际应用中,我们除了可以用final修饰成员变量、成员方法、类,还可以修饰参数、若某个参数被final修饰了,则代表了该参数是不可改变的。

       如果在方法中我们修改了该参数,则编译器会提示你:The final local variable i cannot be assigned. It must be blank and not using a compound assignment。

public class Custom {
    public void test(final int i){
      //i++;     ---final参数不可改变
        System.out.println(i);
    }
    
    public void test(final Person p){
     //p = new Person();    --final参数不可变
     p.setName("chenssy");
    }
}


       同final修饰参数在内部类中是非常有用的,在匿名内部类中,为了保持参数的一致性,若所在的方法的形参需要被内部类里面使用时,该形参必须为final。详情参看:http://www.php.cn/

       五、final与static

       final和static在一起使用就会发生神奇的化学反应,他们同时使用时即可修饰成员变量,也可修饰成员方法。

       对于成员变量,该变量一旦赋值就不能改变,我们称它为“全局常量”。可以通过类名直接访问。

       对于成员方法,则是不可继承和改变。可以通过类名直接访问。

以上就是java提高篇(十四)-----关键字final 的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。