Java プログラミングにおける一般的な問題の概要

高洛峰
リリース: 2017-01-16 16:17:27
オリジナル
1384 人が閲覧しました

この記事では、私の周りの同僚の Java コードで見られる典型的なエラーをいくつかリストします。明らかに、静的コード分析 (私たちのチームは qulice を使用しています) ではすべての問題を見つけることはできないため、ここでそれらをリストします。

何か足りないと思われる場合は、お知らせください。喜んで追加させていただきます。

以下にリストされているこれらのエラーはすべて、基本的にオブジェクト指向プログラミング、特に Java の OOP に関連しています。

もちろん、クラスとインターフェイスを区別するためにプレフィックスやサフィックスを使用しないでください。たとえば、IRecord、IfaceEmployee、または RecordInterface などの名前は間違っています。一般に、インターフェイス名は現実のエンティティの名前である必要があり、クラス名はその実装の詳細を説明する必要があります。実装に特別な点がない場合は、デフォルト、シンプル、または類似したものと呼ぶことができます。例:

class SimpleUser implements User {};
class DefaultRecord implements Record {};
class Suffixed implements Name {};
class Validated implements Content {};
ログイン後にコピー

メソッド名

メソッドは値または void を返すことができます。メソッドが値を返す場合、その名前は何を返すかを説明する必要があります。たとえば (get プレフィックスは使用しないでください):

boolean isValid(String name);
String content();
int ageOf(File file);
ログイン後にコピー

void を返す場合、その名前はその動作を説明する必要があります。例:

void save(File file);
void process(Work work);
void append(File file, String line);
ログイン後にコピー

先ほど述べたルールには例外が 1 つだけあります。JUnit のテスト メソッドは考慮されません。これについては以下で説明します。

テストメソッドの名前

JUnit テストケースでは、メソッド名はスペースを含まない英語のステートメントである必要があります。例を見てみましょう:

/**
 * HttpRequest can return its content in Unicode.
 * @throws Exception If test fails
 */
public void returnsItsContentInUnicode() throws Exception {
}
ログイン後にコピー

JavaDoc の最初の文は、テストするクラスの名前で始まり、その後に can が続く必要があります。したがって、最初の文は「somebody can do something」のようなものにする必要があります。

メソッド名も同じですが、テーマがないだけです。メソッド名の途中に件名を追加すると、上記の例のように、「HttpRequest はコンテンツを Unicode で返します」という完全な文が得られます。

テストメソッドの名前が can で始まらないことに注意してください。 JavaDoc 内のコメントのみ can で始まります。また、メソッド名は動詞で始めてはなりません。

実際には、例外をスローするテスト メソッドを宣言するのが最善です。

変数名

timeOfDay、firstItem、httpRequest などの変数名を組み合わせることは避けてください。これは、クラス変数とメソッド内の変数に当てはまります。変数名は、表示範囲内での曖昧さを避けるために十分な長さである必要がありますが、可能であれば長すぎないようにします。名前は、単数形または複数形の名詞、あるいは適切な略語である必要があります。例:

List<String> names;
void sendThroughProxy(File file, Protocol proto);
private File content;
public HttpRequest request;
ログイン後にコピー

コンストラクターが入力パラメーターを新しく初期化されたオブジェクトに保存したい場合、そのパラメーターの名前とクラス属性が競合することがあります。この場合、私の提案は、母音を削除して略語を使用することです。

例:

public class Message {
  private String recipient;
  public Message(String rcpt) {
    this.recipient = rcpt;
  }
}
ログイン後にコピー

多くの場合、クラス名を見ることで、変数にどのような名前を付ける必要があるかがわかります。次のように信頼性の高い小文字形式を使用してください:

File file;
User user;
Branch branch;
ログイン後にコピー

ただし、整数や文字列などの基本的な型ではこれを決して行わないでください。

異なる性質の変数が複数ある場合は、形容詞の使用を検討できます。例:

String contact(String left, String right);
ログイン後にコピー

コンストラクター メソッド

例外が考慮されない場合、オブジェクト変数にデータを格納するコンストラクター メソッドは 1 つだけである必要があります。他のコンストラクターは、異なるパラメーターを使用してこのコンストラクターを呼び出します。例:

public class Server {
  private String address;
  public Server(String uri) {
    this.address = uri;
  }
  public Server(URI uri) {
    this(uri.toString());
  }
}
ログイン後にコピー

1 回限りの変数

1 回限りの変数は、絶対に避けるべきです。ここで「ワンタイム」とは、一度だけ使用される変数のことを意味します。例:

String name = "data.txt";
return new File(name);
ログイン後にコピー

上記の変数は 1 回だけ使用されるため、このコードは次のように再構成できます:

return new File("data.txt");
ログイン後にコピー

まれに、主に書式設定を改善するために、1 回限りの変数が使用されることがあります。変数。ただし、これはできる限り避けるべきです。

例外

言うまでもなく、例外を自分で飲み込むべきではなく、可能な限り例外を無視する必要があります。プライベート メソッドは常にチェックされた例外をスローする必要があります。

プロセス制御に例外を使用しないでください。たとえば、次のコードは間違っています:

int size;
try {
  size = this.fileSize();
} catch (IOException ex) {
  size = 0;
}
ログイン後にコピー

IOException によって「ディスクがいっぱいです」というプロンプトが表示された場合はどうすればよいですか?ファイルサイズが 0 であると考えて処理を続行しますか?

インデント

インデントに関する主なルールは、左括弧が行末にあるか、同じ行上で閉じている必要があるということです (右括弧の場合はその逆です)。たとえば、次の例は、最初の左括弧が同じ行で閉じられておらず、その後に他の文字があるため、正しくありません。 2 番目の括弧も、その前に文字があるにもかかわらず、対応する左括弧が同じ行にないため問題になります:

final File file = new File(directory,
  "file.txt");
ログイン後にコピー

正しいインデントは次のようにする必要があります:

StringUtils.join(
  Arrays.asList(
    "first line",
    "second line",
    StringUtils.join(
      Arrays.asList("a", "b")
    )
  ),
  "separator"
);
ログイン後にコピー

インデントに関する 2 番目の重要なルールは、次のようにする必要があります。 1 行にできるだけ多くの文字を同時に書き込んでください。上限は 80 文字です。上記の例はこの点を満たしていないため、次のように縮小することもできます:

StringUtils.join(
  Arrays.asList(
    "first line", "second line",
    StringUtils.join(Arrays.asList("a", "b"))
  ),
  "separator"
);
ログイン後にコピー

冗長定数

当你希望在类的方法中共享信息的时候,应当使用类常量,这些信息应该是你这个类所特有的。不要把常量当作字符串或数值字面量的替代品来使用——这是非常糟糕的实践方式,它会对代码造成污染。常量(正如OOP中的任何对象一样)应当在真实世界中有它自己的含义。看下这些常量在真实生活中的意思是什么:

class Document {
  private static final String D_LETTER = "D"; // bad practice
  private static final String EXTENSION = ".doc"; // good practice
}
ログイン後にコピー

另一个常见的错误就是在单元测试中使用常量来避免测试方法中出现冗余的字符串或者数值的字面量。不要这么做!每个测试方法都应该有自己专属的输入值。

在每个新的测试方法中使用新的文本或者数值。它们是相互独立的。那么为什么它们还要共享同样的输入常量呢?

测试数据耦合

下面是测试方法中数据耦合的一个例子:

User user = new User("Jeff");
// maybe some other code here
MatcherAssert.assertThat(user.name(), Matchers.equalTo("Jeff"));
ログイン後にコピー

最后一行中,”Jeff”和第一行中的同一个字符串字面值发生了耦合。如果过了几个月,有人想把第三行这个值换一下,那么他还得花时间找出同一个方法中哪里也使用了这个”Jeff”。


为了避免这种情况,你最好还是引入一个变量。

更多Java编程中的一些常见问题汇总相关文章请关注PHP中文网!

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート