[13] JavaSEのいくつかの一般的な問題

目次

1つは、例外処理です。

2つ、比較可能およびコンパレータ

1.比較可能性を実現する:

2.コンパレータインターフェイスを実装します。

3つ目は、Javaのコンパイル時間と実行時間です。

4つ、hashCode()およびequals()メソッド

5、ファイナライズメソッド

6つのオブジェクト指向、インターフェース指向プログラミング

七、文字列、文字列バッファ、文字列ビルダー


1つは、例外処理です。

エラー

これはプログラムが処理できないエラーであり、OOMなどのコードの実行中にJVMに問題があることを示しています。

例外

プログラムが処理できる例外です。そのサブクラスRuntimeExcptionは、実行時例外を表します。実行時例外以外の例外は、すべて非実行時例外です。

未チェックの例外

ランタイム例外とも呼ばれるコンパイラーは、NullPointerException、IndexOutOfBoundsExcptionなどのプログラマーによって決定される例外処理を必要としません。

チェックされた例外(チェックされた例外、コンパイルされた例外)

非ランタイム例外(ランタイム例外以外の例外は非ランタイム例外)とも呼ばれ、コンパイラーはプログラマーにそれを処理するように強制します。そうしないと、一般的なIOExceptionやSQLExceptionなどのコンパイルがパスしません。

2つ、比較可能およびコンパレータ

Comparableは、クラスで記述された内部コンパレータです。

コンパレータは、比較クラスとは別に記述された外部コンパレータであり、結合は低くなっています。同等のインターフェースを実装するクラスのcompareToメソッドをオーバーライドできます。

コンパレータは、次の2つの状況で使用されます。

1.オブジェクトはそれ自体との比較をサポートしていません(Comparableインターフェイスを実装していません)が、2つのオブジェクトを比較したい

2.オブジェクトはComparableインターフェースを実装しますが、開発者は、compareToメソッドの比較メソッドは彼らが望む種類の比較メソッドではないと考えています(書き直されたcompareToメソッドを書き直し、比較可能なインターフェースを実装するcompareToメソッドをオーバーライドします) )

 

1.比較可能性を実現する:

package testJavaInterfaceAndMethod;

public class Person implements  Comparable<Person>{//本类实现Comparable接口,内比较器方法只需要一个参数

    private int age;

    private String name;

    public Person() {

        

    }

    public Person(int age, String name) {

        super();

        this.age = age;

        this.name = name;

    }

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    @Override

    public int compareTo(Person o) {

        return this.getAge()-o.getAge();

    }

    @Override

    public String toString() {

        return "Person [age=" + age + ", name="  + name + "]";

    }

}

2.コンパレータインターフェイスを実装します。

package testJavaInterfaceAndMethod;

importjava.util.Comparator;

public class PersonComparator implements  Comparator<Person>{//外比较器,方法需要两个参数

//为什么不用重写Comparator中的所有抽象方法

    @Override

    public int compare(Person o1, Person o2) {

        return o2.getAge()-o1.getAge();//注意这里的顺序和实现Comparable接口的compareTo方法属性不一致。

    }

}

テスト:

package testJavaInterfaceAndMethod;

import java.util.Arrays;

import org.junit.Test;

public class Main {

    @Test

    public void testComparable() {

        Person person1 = new Person(22,"dhl");

        Person person2 = new Person(21,"pj");

        Person[] persons = {person1,person2};

        for (int i = 0; i < persons.length; i++)  {

            System.out.println(persons[i]);

        }

        Arrays.sort(persons,new  PersonComparator());//使用外比较器的方法

        for (int i = 0; i < persons.length; i++)  {

            System.out.println(persons[i]);

        }

    }

}

結果:

Person [age=22, name=dhl]

Person [age=21, name=pj]

Person [age=22, name=dhl]

Person [age=21, name=pj]

内部コンパレータと外部コンパレータを同時に使用し、外部コンパレータが優先されます

3つ目は、Javaのコンパイル時間と実行時間です。

コンパイル時:ソースコードをJVMで認識できるバイトコードにコンパイルします

ランタイム:実行するメモリにバイトコードをロードします。

例:

public class ConstantFolding {

static final int number1 = 5;

static final int number2 = 6;

static int number3 = 5;

static int number4= 6;

public static void main(String[ ] args) {

int product1 = number1 * number2; //line A

int product2 = number3 * number4; //line B

}

}

分析:

lineA 是在编译期间计算的。

lineB 是在运行期间计算的。

定数畳み込み、Javaコンパイラで使用される最適化手法です。最終変数の値は変更されないため、最適化できます。

 

メソッドのオーバーロード:これはコンパイル時に発生します。メソッドのオーバーロードは、コンパイラがパラメータのタイプに基づいて使用するメソッドを選択できるため、コンパイル時ポリモーフィズムとも呼ばれます。

例:

public class {

public static void evaluate(String param1); // method #1

public static void evaluate(int param1); // method #2

}

 

メソッドカバレッジ:これは実行時に発生します。メソッドのオーバーロードは、コンパイラがコンパイル時に呼び出すメソッドを認識せず、認識できないため、ランタイムポリモーフィズムと呼ばれますコードの実行中にJVMが決定を下します。

例:

public class A {

public int compute(int input) { //method #3

return 3 * input;

}

}

public class B extends A {

@Override

public int compute(int input) { //method #4

return 4 * input;

}

}

サブクラスBのcompute(..)メソッドは、親クラスのcompute(..)メソッドをオーバーライドします。コンパイラーが次のコードを検出した場合:

public int evaluate(A reference, int arg2) {

int result = reference.compute(arg2);

}

コンパイラーには、渡されたパラメーター参照のタイプがAであるかBであるかを知る方法がありません。したがって、入力変数「参照」に割り当てられたオブジェクトのタイプ(たとえば、AまたはBのインスタンス)に基づいて、実行時にメソッド#3またはメソッド#4のどちらを呼び出すかを決定することしかできません。

 

汎用(型チェックとも呼ばれます):これはコンパイル時に発生します。コンパイラは、プログラム内の型の正確さをチェックし、ジェネリックを使用するコードを現在のJVMで実行できる非ジェネリックコードに変換または書き換える責任があります。この手法は「型消去」と呼ばれます。

つまり、コンパイラは山括弧内のすべての型情報を消去して、JREバージョン1.4.0以前との互換性を確保します。

例:

コンパイル前:

List<Person> myList = new ArrayList(10);

コンパイル後: 

List myList = new ArrayList(10);

4つ、hashCode()およびequals()メソッド

Javaの規則:2つのオブジェクトが等しい場合、hashCodeは等しくなければなりません(ここでのequalsメソッドとhashCodeメソッドは、オーバーライドされないObjectクラスのメソッドを指し、オーバーライドされないequals()メソッドは、オブジェクト(==を使用して直接比較します)。

つまり、2つのオブジェクトのアドレスが同じである場合、それらのhashCodeは同じである必要があり、アドレスが異なる場合は必ずしもそうではありません)が、hashCodeは等しく、オブジェクトは必ずしも等しくなく、hashCodeは等しくない場合、オブジェクトは等しくてはなりません。

1. hashCode()メソッドの主な目的は、ハッシュ構造のストレージでのクエリ効率を向上させることです。

hashCodeメソッドがない場合、HashMapに同じキーが追加されないようにするために、等しい数の要素が必要です。ただし、hashCodeメソッドがある場合、対応するハッシュバケットは次のように検索されます。最初にhashCode値を実行し、次に[等しい比較を実行]を実行して、比較の数を減らします。

2.セットコレクション内の2つのオブジェクトの同等性を判断するための条件、実際には、セットコレクションにデータを格納するか、セットコレクションからデータをフェッチするか(一意性の制御などを含む)は、すべてこの条件によって判断されます。 。条件は次のとおりです。

    まず、2つのオブジェクトのhashCodesが等しいかどうかを判断し、等しくない場合は、2つのオブジェクトが等しくないと見なされ、実行されます。それらが等しい場合、2つのオブジェクトのequals()が等しいかどうかが判断され、等しくない場合、2つのオブジェクトは等しくないと見なされ、等しい場合、2つのオブジェクトは等しいと見なされます。

したがって、セット内の要素の一意性を確保するには、次のようにします。

1. hashCodeメソッドは、equalsメソッドを書き換えた後に書き換える必要があります(hashCodeメソッドを書き換えないでください。equalsですが、hashCodeが異なります。この時点で繰り返されます)

2. equalsメソッドを書き直さずにhashCodeメソッドのみを書き直します。hashCodeは異なりますが、オブジェクトが等しいか、要素が重複している可能性があります。

5、ファイナライズメソッド

Finalizeはjava.lang.Objectクラスで定義されています。このメソッドは、gcが開始され、オブジェクトがリサイクルされる前に呼び出されます。実際、gcはほとんどのオブジェクトをリサイクルできるため、プログラマーは通常finalizeを実装する必要はありません。オブジェクトがリサイクルされるときにリソースを解放する必要があり、この時点でfinalize()メソッドを実装できます。

オブジェクトのfinalize()メソッドは1回しか呼び出すことができません。また、finalize()メソッドが呼び出されても、gcがオブジェクトをすぐに再利用するわけではないため、finalize()が呼び出された後、オブジェクトが呼び出されない可能性があります。オブジェクトが使用されると、finalize()メソッドは以前に呼び出されたため呼び出されず、問題が発生します。さらに、finalize()メソッドは例外を無視します。つまり、finalizeコードで例外が発生した場合、その例外は無視されます。デストラクタとは異なるfinalize()メソッドを積極的に使用しないことをお勧めします(変数の使用範囲を超えるとデストラクタが自動的に呼び出され、デストラクタが呼び出されると変数が破棄されます)。

6つのオブジェクト指向、インターフェース指向プログラミング

すべてがオブジェクトであり、現実のすべてのオブジェクトは物のクラスに属し、すべての個人は物のクラスのインスタンスです。

オブジェクト指向には、カプセル化、継承、ポリモーフィズムという3つの主要な特性があります。

1.カプセル化とは、あるクラスのプロパティと動作をクラスに抽象化し、プロパティをプライベート化して動作を公開し、データのプライバシーを向上させ、コードをモジュール化することです。そうすることで、コードがより再利用可能になります。

2.継承とは、あるクラスによって共有されるプロパティと動作を親クラスにさらに抽象化することです。各サブクラスは、親クラスの動作とプロパティを備えた特別な親クラスであり、独自の動作とプロパティもあります。 。これにより、既存のコードブロックが拡張され、コードの再利用性がさらに向上します。

3.カプセル化と継承がコードの再利用のためのものである場合、ポリモーフィズムはインターフェースの再利用のためのものです。ポリモーフィズムの主な機能は、親子クラスの継承の結合度を削除するために、分離することです。継承における親クラスと子クラスの関係がIS-Aであるとすると、インターフェースと実装クラスの関係はHAS-Aになります。簡単に言えば、ポリモーフィズムとは、親クラスの参照(またはインターフェイス)がサブクラス(または実装クラス)オブジェクトを指すことを可能にすることです。多くのデザインパターンは、オブジェクト指向のポリモーフィズムデザインに基づいています。

要約すると、カプセル化と継承がオブジェクト指向の基礎である場合、ポリモーフィズムはオブジェクト指向理論の本質です。ポリモーフィズムを習得するには、最初にインターフェースを理解する必要があります。インターフェースを完全に理解することによってのみ、ポリモーフィズムをより適切に適用できます。

インターフェイス指向プログラミング:インターフェイスも一種の仕様です!インターフェイス指向プログラミングは、実際には会社の規制に準拠することに似ています。これにより、システムの柔軟性と保守性が向上し、影響が軽減されます。プロジェクトでよく言われることを理解してください:高い凝集度、低い結合度!

七、文字列、文字列バッファ、文字列ビルダー

文字列文字列定数; StringBuffer文字列変数(スレッドセーフ); StringBuilder文字列変数(非スレッドセーフ)

文字列S1 =「これはただの」+「単純」+「テスト」;

実際:String S1 = "これは単純なテストにすぎません"

文字列が頻繁に変更される場合、速度:StringBuilder> StringBuffer> String

おすすめ

転載: blog.csdn.net/Jack_PJ/article/details/88038129