ホームページ  >  記事  >  Java  >  Java でよくあるいくつかのエラーの紹介

Java でよくあるいくつかのエラーの紹介

尚
オリジナル
2019-12-23 15:43:284610ブラウズ

Java でよくあるいくつかのエラーの紹介

一般的な Java エラー:

1. Null ポインター エラー

Java 配列の使用では、配列内の要素を変更する必要がある場合があります。文字列配列の比較。要素が null でない場合、プログラムは正常に実行されますが、比較された要素が null になると、プログラム内で null ポインタ エラーが発生します。

解決策: 保護を追加し、要素が null でない場合に判定を行います。

public static void main(Sring[] args){
  String [] sums = "adfafA";
  for(int i=0;i<sums.length;i++){
    if(sums[]!=null && sums[i].equals(sr)){
      System.out.println("找到元素"+sums[i]);
      break;
    }
  }
}

2. データ精度範囲と型変換

Java には 4 つの基本的なデータ型があります:

整数型: -1 2 3 4 ……

浮動小数点型: float 1.3f; double 3.2 3.5d (未指定型、デフォルトの最高精度)

文字型: Unicode エンコード、2 バイト

ブール型: の精度範囲true と false

という 4 つの基本的なデータ タイプは異なり、段階的に改良されています。

データ型を使用する際に精度の範囲に注意しないと、データのオーバーフローが発生し、計算エラーが発生します。

4 つの基本型のうち、整数、浮動小数点、および文字データは相互に変換できます。

変換ルールは以下のとおりです。

①目に見えない変換:精度の低いデータ値を精度の高い値に代入し、自動的に変換できます。 (下位から上位へ)

②強制変換:範囲の広いデータ値、(上位から下位へ)

③運用自動昇格ルール:運用中、これは自動的に高精度のデータ型に変換されます。

3. 3種類のループの使い方

①forループ: 回数制限のあるループであり、ループの前にループ回数を指定します。

for(表达式;表达式;表达式){
        循环体
 }

break ステートメント: 実行後、すぐにループから抜け出し、後続のステートメントを実行せず、すべてのループを終了します。

continue 文: 実行後、直ちに現在のワードループから抜け出し、条件がループ継続するかどうかを再判定します。

②while ループ文: 回数が不明なループに適しています。

while(条件表达式){
  语句
 };

③do-while ループ: これも回数不明のループです。注文は判断を下す前に少なくとも 1 回執行される必要があります。 while が true の場合はループを継続し、そうでない場合はループを終了します。

do {
 语句
 }while(条件表达式);

4. 文字列を複数回コピーします

テストでは発見できないエラーが、不変オブジェクトのコピーを複数生成しています。不変オブジェクトは変更できないため、コピーする必要はありません。最も一般的に使用される不変オブジェクトは String です。

String オブジェクトの内容を変更する必要がある場合は、StringBuffer を使用する必要があります。次のコードは正常に動作します:

String s = new String ("Text here");

ただし、このコードはパフォーマンスが低く、必要以上に複雑です。上記のコードを次のように書き直すこともできます:

String temp = "Text here";
String s = new String (temp);

ただし、このコードには追加の文字列が含まれていますが、これは完全には必要ではありません。より良いコードは次のとおりです:

String s = "Text here";

5. クローンによって返されるオブジェクトはありません。

カプセル化は、オブジェクト指向プログラミングにおける重要な概念です。残念ながら、Java ではカプセル化が誤って破られやすくなっています。Java ではプライベート データへの参照を返すことができます。次のコードはこれを明らかにします:

import java.awt.Dimension;
  /***Example class.The x and y values should never*be negative.*/
  public class Example{
  private Dimension d = new Dimension (0, 0);
  public Example (){ }
  /*** Set height and width. Both height and width must be nonnegative * or an exception is thrown.*/
  public synchronized void setValues (int height,int width) throws IllegalArgumentException{
  if (height <0 || width <0)
  throw new IllegalArgumentException();
  d.height = height;
  d.width = width;
  }
  public synchronized Dimension getValues(){
  // Ooops! Breaks encapsulation
  return d;
  }
  }

サンプル クラスは、格納される高さと幅の値が常に非負であることを保証します。setValues() メソッドを使用して負の値を設定しようとすると、例外。残念ながら、getValues() は d のコピーではなく d への参照を返すため、次のような破壊的なコードを書くことができます:

  Example ex = new Example();
  Dimension d = ex.getValues();
  d.height = -5;
  d.width = -10;

Now, Example オブジェクトには負の値があります! getValues() への呼び出しがユーザーが返された Dimension オブジェクトの幅と高さの値を設定しない場合、テストだけでそのようなエラーを検出することは不可能です。

残念ながら、時間の経過とともに、クライアント コードによって返された Dimension オブジェクトの値が変更される可能性があります。現時点では、特にマルチスレッド環境では、エラーの原因を追跡するのは面倒で時間がかかります。

より良い方法は、getValues() にコピーを返させることです:

  public synchronized Dimension getValues(){
  return new Dimension (d.x, d.y);
  }

6. 間違ったデータをコピーします

プログラマーはコピーを返さなければならないことを知っていても、間違ったデータをコピーしないように注意してください。データ コピー作業の一部しか行われていないため、次のコードはプログラマの意図から逸脱しています:

import java.awt.Dimension;
  /*** Example class. The height and width values should never * be
  negative. */
  public class Example{
  static final public int TOTAL_VALUES = 10;
  private Dimension[] d = new Dimension[TOTAL_VALUES];
  public Example (){ }
  /*** Set height and width. Both height and width must be nonnegative * or an exception will be thrown. */
  public synchronized void setValues (int index, int height, int width) throws IllegalArgumentException{
  if (height <0 || width <0)
  throw new IllegalArgumentException();
  if (d[index] == null)
  d[index] = new Dimension();
  d[index].height = height;
  d[index].width = width;
  }
  public synchronized Dimension[] getValues()
  throws CloneNotSupportedException{
  return (Dimension[])d.clone();
  }
  }

ここでの問題は、getValues() メソッドが配列の複製のみを作成し、Dimension オブジェクトの複製を作成しないことです。したがって、呼び出し元は、内部配列の要素が別の Dimension オブジェクトを指すように内部配列を変更することはできませんが、内部配列要素 (つまり、Dimension オブジェクト) の内容を変更することはできます。 getValues() メソッドのより良いバージョンは次のとおりです。

 public synchronized Dimension[] getValues() throws CloneNotSupportedException{
  Dimension[] copy = (Dimension[])d.clone();
  for (int i = 0; i
  // NOTE: Dimension isn’t cloneable.
  if (d != null)
  copy[i] = new Dimension (d[i].height, d[i].width);
  }
  return copy;
  }

アトミック型データの多次元配列を複製するときにも、同様の間違いが発生します。アトミック タイプには、int、float などが含まれます。以下に示すように、単純に int 型の 1 次元配列を複製するのは正しいことです。

 public void store (int[] data) throws CloneNotSupportedException{
  this.data = (int[])data.clone();
  // OK
  }

int 型の 2 次元配列のコピーはより複雑です。 Java には int 型の 2 次元配列がないため、int 型の 2 次元配列は実際には 1 次元配列であり、その型は int[] です。 int[][] 型の配列を単純に複製すると、上記の例の getValues() メソッドの最初のバージョンと同じ間違いが発生するため、これは避けるべきです。次の例は、2 次元 int 配列を複製するときの間違ったメソッドと正しいメソッドを示しています。

public void wrongStore (int[][] data) throws CloneNotSupportedException{
  this.data = (int[][])data.clone(); // Not OK!
  }
  public void rightStore (int[][] data){
  // OK!
  this.data = (int[][])data.clone();
  for (int i = 0; i
  if (data != null)
  this.data[i] = (int[])data[i].clone();
  }
  }

Java の詳細については、「java Basic Tutorial」列に注目してください。

以上がJava でよくあるいくつかのエラーの紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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