java importがパッケージをインポートするとき、何に注意を払う必要がありますか?

javaインポートインポートパッケージ

こんにちは、私は山を見ています。

この記事の理由は、コードレビュー中のインポートステートメントに関する同僚との意見の相違です。

IDEAを使用したことのある人は、デフォルトで、インポートを介してクラスをインポートするときに、その数が設定された数(5クラス、3静的変数)に達すると、オンデマンドインポート方式に変更されることを知っています。つまり、*を使用します。インポートを折りたたむための署名。

同僚は、オンデマンドインポートを使用するのではなく、シングルタイプインポートを使用することを提案しています。そして、IDEAはユニバースレベルのIDEなので、このような場所で間違いはないと思いますので、引き続きIDEAのデフォルト設定に従いたいと思います。

したがって、これら2つの方法の違いを要約してください。Javaインポートに慣れていない場合は、ここから見てください。

輸入の2つの輸入宣言

Javaでは、インポートを介してクラスをインポートする方法は2つあります。

  • 単一タイプのインポート(単一タイプのインポート)の例import java.io.File:この方法は理解しやすく、ほとんどの場合、この方法を使用します。クラスとインターフェイスパスを明確に指定して、それらをインポートします。
  • たとえばimport java.io.*Type-import-on-demand(type-import-on-demand)は、ワイルドカードを使用*してインポート方法定義しますが、このパッケージのすべてのクラスが直接インポートされるわけではありませんが、すべてのクラスをインポートできます。つまり、インポートする必要がある場合、不要な場合はインポートしないでください。

次の属性があります。

  1. Javaはpublicこれら2つの方法でパッケージのいずれかのクラスとインターフェイスをインポートます(パブリッククラスとインターフェイスのみをインポートできます)
  2. 上記のように、インポート宣言は、宣言ディレクトリの下のクラスのみをインポートし、サブパッケージはインポートしません。そのため、これらはタイプインポート宣言と呼ばれます。
  3. インポートされたクラスまたはインターフェースの単純な名前には、コンパイル単位のスコープがあります。これは、タイプの短い名前が、importステートメントが配置されているコンパイル単位のどこでも使用できることを意味します。これは、型のすべてのメンバーの短縮名を使用できることを意味するのではなく、型自体の短縮名のみを使用できることを意味します。例:java.langパッケージ内のパブリッククラスは自動的に含めて、インポートされMathおよびSystemクラス。ただし、使用することはできませんPI()総和そのメンバーの短い名前のをgc()、しかし使用する必要がありますMath.PI()合計をSystem.gc()。あなたが入力する必要はありませんjava.lang.Math.PI()合計をjava.lang.System.gc()
  4. プログラマーjava.langは、現在のパッケージのメンバー自体がスコープ内にあり、java.langパッケージが自動的にインポートされるため、現在のパッケージまたはパッケージをインポートすることがありますが、これは不要です。Javaコンパイラは、これらの冗長なインポート宣言を無視します。

オンデマンドのインポートメカニズム

ほとんどの場合、オンデマンドタイプのインポートの方が便利です。ワイルドカードを使用すると、パッケージ内のすべてのクラスをインポートできるため、多くのインポートを作成する必要はありません。

しかし、エネルギー保存の法則によれば、コードを入力するときに節約されたエネルギーは、必然的に他の場所で消費されます。

たとえば、Dateオンデマンドタイプを使用して完全にインポートされた場合クラスを作成できますimport java.util.*このクラスが必要になった場合は、インポートPrepareStatementを追加する必要がありますimport java.sql.*。この時点で、コンパイラはDateクラスがjava.utilパッケージjava.sql内で使用されるの内部で使用されるのかわからないReference to 'Date' is ambiguous, both 'java.util.Date' and 'java.sql.Date' matchため、いわゆるネーミングと呼ばれる例外を報告します。競合

解決策はDate、クラスへのフルパスを指定することです。つまり、単一のタイプのインポートを使用しますimport java.util.Date

名前の競合に加えて、あまり明白ではない欠点がいくつかあります。

  1. コンパイル速度:オンデマンドインポートメカニズムの特性により、CLASSPATHの下のパッケージ名に一致するすべてのクラスを見つける必要があります。これにより、コンパイル中にパフォーマンスが低下します。小さなプロジェクトでは、この速度は無視できます。大規模なプロジェクトの場合、詳細な違いがあります。
  2. 読みやすさ:IDEを使用した開発プロセスimportでは、クラスのパスを確認することはめったにありませんただし、vimなどの他の環境でファイルを編集する必要がある場合はimport、クラスのパスを表示すると非常に便利です。

不要なクラスをインポートするとどうなりますか

合理的な観点から、Javaコンパイラはここで確実に最適化し、クラスファイルに不要なインポート宣言を追加しませんが、これまでに命令を見たことがないので、いくつかの実験を行いましょう。

まず、Javaクラスを定義します。

package cn.howardliu;

// 需要用到的单类型导入
import java.util.Date;
// 需要用到的按需类型导入
import java.math.*;
// 不需要用到的单类型导入
import java.sql.PreparedStatement;
// 不需要用到的按需类型导入
import java.awt.*;

public class Main {
    
    
    private Date date1;
    private BigDecimal num1;

    public void test(){
    
    
        Date date2 = new Date();
        BigDecimal num2 = new BigDecimal(0);
    }
}

コマンドjavac Main.javaでコンパイルしてjavap -verbose Main.classから、コンパイルの結果を表示します。

Classfile /path/to/Main.class
  Last modified 2021-1-31; size 439 bytes
  MD5 checksum 81e13559f738197b4875c2c2afd6fc41
  Compiled from "Main.java"
public class cn.howardliu.Main
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #7.#19         // java/lang/Object."<init>":()V
   #2 = Class              #20            // java/util/Date
   #3 = Methodref          #2.#19         // java/util/Date."<init>":()V
   #4 = Class              #21            // java/math/BigDecimal
   #5 = Methodref          #4.#22         // java/math/BigDecimal."<init>":(I)V
   #6 = Class              #23            // cn/howardliu/Main
   #7 = Class              #24            // java/lang/Object
   #8 = Utf8               date1
   #9 = Utf8               Ljava/util/Date;
  #10 = Utf8               num1
  #11 = Utf8               Ljava/math/BigDecimal;
  #12 = Utf8               <init>
  #13 = Utf8               ()V
  #14 = Utf8               Code
  #15 = Utf8               LineNumberTable
  #16 = Utf8               test
  #17 = Utf8               SourceFile
  #18 = Utf8               Main.java
  #19 = NameAndType        #12:#13        // "<init>":()V
  #20 = Utf8               java/util/Date
  #21 = Utf8               java/math/BigDecimal
  #22 = NameAndType        #12:#25        // "<init>":(I)V
  #23 = Utf8               cn/howardliu/Main
  #24 = Utf8               java/lang/Object
  #25 = Utf8               (I)V
{
  public cn.howardliu.Main();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 12: 0

  public void test();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=1
         0: new           #2                  // class java/util/Date
         3: dup
         4: invokespecial #3                  // Method java/util/Date."<init>":()V
         7: astore_1
         8: new           #4                  // class java/math/BigDecimal
        11: dup
        12: iconst_0
        13: invokespecial #5                  // Method java/math/BigDecimal."<init>":(I)V
        16: astore_2
        17: return
      LineNumberTable:
        line 17: 0
        line 18: 8
        line 19: 17
}
SourceFile: "Main.java"

これは、クラスファイルの内容から確認できます。

  1. クラスファイルでのオンデマンドタイプインポートメソッドの表示は、タイプ別インポートと同じです。必要なクラスインポートが見つかり、パッケージ内のすべてのクラスがインポートされるわけではありません。
  2. 不要なクラスインポート宣言は最終的に最適化され、クラスファイルには表示されません。
  3. importC言語とは異なり、Javaincludeはインポートされた宣言済みクラスをクラスファイルに書き込みません。それぞれが独立したクラスファイルです。

JDKはどちらの方法を推奨します

JDKは間違いなくJavaプログラミングのベンチマークです。私たちの多くはJDKから学ぶことができます。

import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.security.AccessController;
import java.security.PrivilegedAction;

import sun.util.spi.XmlPropertiesProvider;

これはjava.util.Propertiesのインポートステートメントです。単一タイプのインポートステートメントが使用されていることがわかります。したがって、他の要件がない場合は、可能な限り単一タイプのインポートを使用するようにしています。

文末思考

  1. Javaimportはクラスインポート宣言であり、コンパイルされたクラスファイルにファイルを書き込みません。
  2. Javaには、importシングルタイプのインポートとオンデマンドタイプのインポートの2つのインポート方法があります。
  3. オンデマンドタイプのインポートでは、コンパイルプロセス中にのみパフォーマンスが低下し、実行時のシングルタイプのインポートに違いはありません。
  4. ほとんどのJDKソースコードは単一タイプのインポートを使用します。

こんにちは、私はKanshanです。パブリックアカウント:Kanshan’s Lodge、10歳のバックエンド、Apache Storm、WxJava、Cynomysのオープンソース寄稿者。主な仕事:プログラマー、アルバイト:建築家。コードの世界で泳ぎ、ドラマでの生活を楽しんでください。

個人のホームページ:https
//www.howardliu.cn個人のブログ投稿:java import import package
CSDNホームページ:http:
//blog.csdn.net/liuxinghao CSDNブログ投稿:java import import package

公開番号:山小屋を見る

おすすめ

転載: blog.csdn.net/conansix/article/details/113487825