パパの勉強部屋

勉強の記録をつけています。Java、ネットワーク、Excel、etc.

Windows フォルダ内をツリー表示する

フォルダ内をツリー表示する

サブフォルダをツリー表示

tree C:\work\ex64

フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 000000D0 8CFB:AE8B です
C:\WORK\EX64
└─comment

サブフォルダおよびファイル名をツリー表示

tree C:\work\ex64 /f

フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 000000F7 8CFB:AE8B です
C:\WORK\EX64
│  Kouhan.java
│  Main.class
│  Main.java
│  Zenhan.java
│
└─comment
        Kouhan.class
        Zenhan.class

ツリー表示をファイルに出力する

tree C:\work\ex64 /f >C:\work\tree.txt

C:\work\tree.txt

フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は 000000B2 8CFB:AE8B です
C:\WORK\EX64
│  Kouhan.java
│  Main.class
│  Main.java
│  Zenhan.java
│  
└─comment
        Kouhan.class
        Zenhan.class

スッキリわかるJava入門 第6章 複数のクラスを用いた開発②

第6章 複数のクラスを用いた開発②

Java API

javaコマンドに特殊なオプションを指定してHelloWorldプログラムを実行。
java -verbose:class HelloWorld
  • 348行の「Loaded ~.~.~」が表示される。(環境によるが)
  • HelloWorldプログラムが動作するためにJVMに読み込まれたクラスのFQCN
  • 1つのクラスが、ほかの347個のクラスと連携して動く、計348クラスからなるプログラム。
  • 347このクラスは、Javaに初めから標準添付されているクラスであり、API(Application Programing Interface)と総称される。
API利用の例(並べ替え)
  • java.utilパッケージのArraysクラスにあるsortメソッドを呼び出している。
  • java.util.ArraysはJavaが標準で提供するAPIの一部である。
  • APIに含まれる3,500個を超えるクラスは、それぞれクラスファイル(Arrays.classなど)の形で、JDKをインストールした際にコンピュータにコピーされている。

public class Main {
  public static void main(String[] args) {
    int[] heights = {172, 149, 152, 191, 155};
    java.util.Arrays.sort(heights);
    for (int h : heights) {
      System.out.println(h);
    }
  }
}

APIで提供されるパッケージ

代表的なAPIパッケージ
  • java.lang Javaに欠かせない、重要なクラス群
  • java.util プログラミングを便利にするさまざまなクラス群
  • java.math 数学に関するクラス群
  • java.net  ネットワーク通信などを行うためのクラス群
  • java.io  ファイル読み書きなど、データを逐次処理するためのクラス群
  • java.langパッケージに属するクラスは頻繁に利用するものが多い。import文を記述せずとも、自動的にインポートされる。
  • 代表的なクラス:System,Integer,Math,Object,String,Runtimeなど
APIリファレンス
  • ①左上のフレーム:調べたいクラスが所属するパッケージ名をクリック
  • ②左下のフレーム:調べたいクラス名をクリック
  • ③右側のフレーム:表示されるクラスの説明を読む

docs.oracle.com
 

クラスが読み込まれるしくみ

  • JVMが必要なクラスファイルを読み込む処理をクラスローディング(class loading)と言う。
  • JVMは起動直後にすべてのクラスを読み込むようなことはしない。使わないクラスまでロードしていたらムダにメモリを消費し、動作も遅くなる。
  • 一部の例外を除いて「必要になった時に、必要なクラスだけ」読み込む。
  • JVMの中でクラスファイルを読み込む仕事をしているのはクラスローダー(class loader)という部分。
  • JVMがクラスローダーに対して「Calc」クラスを利用するから読み込んで利用可能にしなさい」と指示を出す。クラスローダーはコンピュータのハードディスクの中にあるCalc.classを読み込む。JVMは使いたいクラス名を指定しているだけであって、クラスファイルがハードディスクのどこのフォルダにあるのかを一切指定していない。
  • クラスローダーはクラスパス(classpath)というヒント情報をを使うことで、極めて高速に目的のクラスファイルを探し出す。クラスパスとは「クラスローダーがクラスファイルを探す際に、見に行くべきフォルダの場所」のこと。

  

クラスパスの指定方法

方法1:起動時にjavaコマンドで指定する。
  • javaコマンドでJVMを起動する際に -cp オプション または -classpath オプションで指定する。
  • >java -cp c:\work Calc
方法2:検索場所をOSに登録しておく
  • OSの「環境変数」にクラスパスを登録する。
方法3:特に指定しない
  • 上記1、2の指定が無い場合、デフォルトではjavaコマンドが実行されたフォルダがクラスパスとなる。

クラスパスで指定できる対象

対象1:フォルダの場所
  • クラスファイルが置かれているフォルダの場所(絶対パス)を指定する。
  • 「c:\work」を指定すると、フォルダ内のクラスファイルが検索対象となる。
対象2:クラスファイルが入ったJARファイルやZIPファイル
  • クラスファイルが入っているJARファイルやZIPファイルの場所(絶対パス)を指定する。
対象3:複数のフォルダ、JAR/ZIPファイル、それらの組み合わせ
  • クラスパスとして、複数のフォルダ、JARファイルをデリミタ文字で区切って指定できる。
  • デリミタ文字はWindowsセミコロン(;)、LinuxMacはコロン(:)。

クラスパスに自動的に加わるrt.jar

  • javaコマンドでクラスファイルを実行する際、特に指定しなくてもrt.jar(またはclasses.jar)というファイルがクラスパスに追加される。
  • このファイルはJDKに含まれているもので、Javaをインストールしたフォルダの配下にあるlibフォルダの中に含まれている。
  • zipファイルの展開ツールで展開すると、たくさんのフォルダとクラスファイルがある。膨大な数のAPIクラス群の実体。

javaコマンドの正確な構文

  • >java 起動したいクラスの完全限定クラス名(FQCN
  • >java calcapp.main.Calc

java と javac の引数

  • javaコマンド :「どのソースファイルをコンパイルするか」をファイル名で指定して実行するもの。
  • javacコマンド:「どのクラスのmainメソッドを起動するか」をクラス名(FQCN)で指定して実行するもの。

クラスローダーの動作原則

  • あるパッケージx.y.zに属するクラスCを探す場合、クラスローダーは「クラスパスで指定されたフォルダ\x\y\z\C.class」というファイルを読み込もうとする。
  • 現在のクラスパスを基準場所にしてパッケージ階層に対応したフォルダ階層を作り、その中に必要なクラスファイルを配置しておく必要がある。
  • 例)「c:\work」をクラスパスとする場合

  Calc.class(package calcapp.main) ⇒c:\work\calcapp\main フォルダへ
  CalcLogic.class(package calcapp.logics) ⇒c:\work\calcapp\logics フォルダへ

スッキリわかるJava入門 第6章 複数のクラスを用いた開発①

●ソースファイルを分割する
 ・複数のソースファイルに分けて開発する=複数のクラスに分けて開発する。
 ・ファイルごとに開発を分担し、それぞれが並行して開発を進められる。(=分業しやすい)
 ・1つのプログラムを複数の部品に分けることを部品化という。
 ・別クラスのメソッドを呼び出すときの記述。
  ・int total = CalcLogic.tasu(a,b); ⇒CalcLogicクラスのtasu()
  ・int delta = CalcLogic.hiku(a,b); ⇒CalcLogicクラスのhiku()

●複数クラスのコンパイル
 ・javacコマンドで複数のソースファイルを指定する。
  > javac Calc.java CalcLogic.java … Calc.class CalcLogic.class
  ⇒それぞれのソースファイルに対応したクラスファイルが作成される。

Javaプログラムの完成品
 ・Javaプログラムの完成品は、複数のクラスファイルの集合体。
 ・誰かに配布する際は、すべてのクラスファイルを渡す必要がある。
  ⇒上の例の場合、Calc.class CalcLogic.classを渡す。
 ・JVMは起動時に指定されたクラスの中にあるmainメソッドを呼び出してプログラムの実行を開始する。
 ・実行する場合は「渡された複数のクラスファイルのうち、mainメソッドが含まれているクラスの名前」を指定する必要がある。

●JARファイルとは?
 ・プログラムの完成品が複数のクラスファイルだと、メールで送る際などに不便。
 ・Javaでは「複数のクラスファイルを1つにまとめるファイル形式」としてJAR(Java ARchive)が定められている。
 ・JARファイルはZIPファイルととてもよく似たアーカイブファイルであり、JDKに付属するjarコマンドでも作成することができる。

●パッケージを利用する
 ・各クラスをパッケージ(package)というグループに所属させて、分類・管理する仕組み。
 ・クラスがあるソースコードの先頭にpackage文を記述する。
  package 所属させたいパッケージ名;
  (ただし package 文はソースコードの先頭に記述する)
 ・アルファベットは小文字を使う事が一般的。
 ・「calcapp.main」や「calcapp.logics」のようにドットで区切ったパッケージ名も多く用いられる。
 ・「calcapp.main」や「calcapp.logics」のように、パッケージ名の一部が同じであっても、それぞれのパッケージに関連性はない。
  ⇒パッケージに親子関係・階層関係は無い。
 ・どのパッケージにも所属していないことを「無名パッケージに属している」または「デフォルトパッケージに属している」と表現する。
 ・別パッケージに属しているクラスを利用する場合、所属パッケージ名を添えたクラス名を利用する。
  ・int total = Calcapp.logics.CalcLogic.tasu(a,b);
  ・int delta = Calcapp.logics.CalcLogic.hiku(a,b);
 ・あるクラスから別パッケージのクラスを利用する場合、「パッケージ名を頭につけた完全なクラス名」を使う必要がある。
  ⇒完全はクラス名のことを、完全限定クラス名(full qualified class name)、または略してFQCNと言う。

名前空間
 ・パッケージを使うもう一つのメリット
  ⇒自分が作るクラスに対して、開発者が自由な名前を付けられるようにすること
 ・大規模な開発になると、複数の開発者が偶然「同じクラス名を使ってしまう」可能性が出てくる。
  ⇒内容が異なる別々のクラスで同じ名前を取り合ってしまうことを「名前の衝突」と言う。
 ・Javaではパッケージが異なれば、同じクラス名を使ってよい事になっている。
  ⇒クラス名が同一でも、パッケージ名が異なれば完全限定クラス名(FQCN)が異なるので両者は区別できる。
   パッケージを使う事によって、それぞれのパッケージ内では自由にクラス名を付ける事が可能になる。
 ・パッケージ名が衝突すると、これらの前提はすべて崩れてしまう。
 ・推奨されるパッケージ名
  ⇒パッケージ名は「保有するインターネットドメインを前後逆順にしたもの」から始める。
 ・例)foo.example.comというインターネットドメインを取得している企業
  ⇒com.example.fooで始まるパッケージ名を使う。
   インターネットドメインは世界に一つだけなので、パッケージ名が衝突する事はない。
   com.example.fooより後は、企業や組織内部でパッケージ名が衝突しないように調整すればよい。
 ・import文を使うことで、FQCN入力のめんどうさを軽減できる。
  import パッケージ名.クラス名;
  ※import文はソースコードの先頭に、ただしpackage文より後に記述する。
  ⇒頻繁に利用するクラスはimport文を使ってインポートしておくことによって、毎回完全限定クラス名を書く必要がなくなる。
 ・calcapp.logicsパッケージに所属するすべてのクラスをインポートしたい場合
  import calcapp.logics.*;
  ⇒ただし「calcapp.*;」という記述では、calcapp.mainとcalcapp.logicsに所属するすべてのクラスを一度にインポートできないことに注意。
   この指定では「calcappパッケージに所属する全クラス」がインポートされる。

●import宣言は、あくまで「めんどうさ軽減機能」
 ・Javaでは、一切の宣言をすることなく、JVMが扱えるすべてのクラスを常時使うことができる。
 ・ただし、利用に際しては必ずFQCNを利用しなければならず、import文はあくまでFQCNの記述を省略できるだけ。
  ⇒めんどうを軽減するため(開発者がラクをするため)の構文にすぎない。
 ・importしたからといって利用できるクラスやメソッドが増えたり、プログラムから利用できる機能が増えたりする事はない。

スッキリわかるJava入門 第5章 メソッド(練習問題)

練習5-1

package sample;

public class JavaR05_01 {
	public static void main (String[] args) {
		introduceOneself();
	}

	public static void introduceOneself() {
		String name = "吉田 正尚";
		int age = 29;
		double height = 172.7;
		String sex = "男";

		System.out.println("名前: " + name);
		System.out.println("年齢: " + age);
		System.out.println("身長: " + height);
		System.out.println("性別: " + sex);
	}
}

●実行結果
名前: 吉田 正尚
年齢: 29
身長: 172.7
性別: 男

練習5-2

package sample;

public class JavaR05_02 {
	public static void main (String[] args) {
		email("WBC", "mura-kamisama@samurai.co.jp", "顔を上げて頑張れ!");
		email("mura-kamisama@samurai.co.jp", "顔を上げて頑張れ!");
	}

	public static void email (String title, String address, String text) {
		System.out.println(address + "に、以下のメールを送信しました");
		System.out.println("件名:" + title);
		System.out.println("本文:" + text);
	}

	public static void email (String address, String text) {
		System.out.println(address + "に、以下のメールを送信しました");
		System.out.println("件名:無題");
		System.out.println("本文:" + text);
	}
}

●実行結果
mura-kamisama@samurai.co.jpに、以下のメールを送信しました
件名:WBC
本文:顔を上げて頑張れ!
mura-kamisama@samurai.co.jpに、以下のメールを送信しました
件名:無題
本文:顔を上げて頑張れ!

練習5-4

package sample;

public class JavaR05_04 {
	public static void main (String[] args) {
		// 三角形の面積
		double bottom = 10.0;
		double height = 5.0;
		System.out.println("三角形の面積");
		System.out.println("底辺:" + bottom);
		System.out.println("高さ:" + height);
		System.out.println("面積:" + calcTriangleArea(bottom, height));

		// 円の面積
		double radius = 5.0;
		System.out.println("円の面積");
		System.out.println("半径:" + radius);
		System.out.println("面積:" + calcCircleArea(radius));
	}

	public static double calcTriangleArea (double bottom, double height) {
		return bottom * height / 2;
	}

	public static double calcCircleArea(double radius) {
		return radius * radius * 3.14;
	}
}

●実行結果
三角形の面積
底辺:10.0
高さ:5.0
面積:25.0
円の面積
半径:5.0
面積:78.5

スッキリわかるJava入門 第5章 メソッド

●メソッド(method)
 ・Javaでは1つのプログラムを複数の部品に分けて作る事ができる。
 ・複数の文をまとめて名前を付けたもので、部品の最小単位。
 ・機能単位でメソッドに分割する事で、プログラムの「大局」を見渡せることができるようになり、全体の把握が楽になる。
 ・「表示がおかしい」など不具合が出た場合には、それを担当するメソッドを調べればよいため、修正が楽になる。
 ・繰り返し使用する事ができるので、同じ処理を何度も書く必要もなくなり、コードを書く手間を省くこともできる。

●メソッドの定義
 ・クラスブロックで以下の構文を使用。
  public static 戻り値の型 メソッド名 (引数リスト) {
   メソッドが呼び出されたときに実行される具体的な処理
  }
  
  例)
  public static void hello () {
   System.out.println("こんにちは");
  }
  ・hello ⇒定義するメソッドの名前(メソッド名)
  ・{}の中 ⇒メソッドブロック、helloメソッドを呼び出した時に実行される具体的な処理

●引数(argument)
 ・メソッドを呼び出す際に、呼び出し元から値を渡すことができる。
 ・渡される値の事を引数(argument)と言う。
 ・渡す値の事を「実引数」、受け取る変数の事を「仮引数」と呼ぶ。
 ・値の渡し方
  何も渡さない場合:メソッド名 ()
  値を1つ渡す場合:メソッド名 ( 値 )
  値を複数渡す場合:メソッド名 ( 値, 値, … )
  ※値の箇所には、変数名を指定することもできる。

●ローカル変数
 ・メソッド名で宣言した変数。仮引数もその一種。
 ・変数が属するメソッド内だけで有効な存在。
 ・別のメソッドに属する同名のローカル変数とは全くの別物。

●戻り値
 ・呼び出されたメソッドから、呼び出し元のメソッドへ値を返す事を「値を戻す」と言う。
 ・戻されるデータ(値)の事を「戻り値」と言う。
 ・値の戻し方
  public static 戻り値の型 メソッド名 (引数リスト …) {
   メソッドが実行された時に動く処理
   retrun 戻り値;
  }
 ・戻り値の型
  retuenによって戻される値と同じ型を指定する。
  何も戻さない場合は「void」を指定する。(voidは何もないという意味)
 ・戻り値を受け取る
  型 変数名 = メソッド名(引数リスト);
  ・変数を用意して受け取る必要がある。
  ・「=」がある場合、常に右辺から先に評価されるので、まずはメソッドの呼び出しが実行される。
  ・呼び出されたメソッドがreturn文によって値を戻す場合
   ⇒メソッド名(引数リスト)という部分は、評価されて戻ってきた値に置き換わる。
 ・メソッドの戻り値を変数で受けずに、そのまま使うこともできる。
 ・戻り値があるが使わない場合は、メソッド名(引数リスト)で呼び出すだけでも良い。
 ・return文は値を戻すだけでなく、メソッドの終了も行う。

オーバーロード
 ・似たような処理を行うメソッドを複数作りたい場合。
  ⇒メソッドに同じ名前をつけることは基本的にはできない。
 ・同じ名前のメソッドを定義する事をオーバーロード(overload)(または多重定義)と言う。
 ・仮引数が異なれば同じ名前のメソッドを複数定義することが許されている。
  ⇒JVMが呼び出し元の引数(実引数)を見て、その引数の型に一致するメソッドを呼び出す。
 ・仮引数の型だけでなく個数が違う場合もオーバーロードできる。
  ⇒JVMは引数の型と個数を比較して一致する方のメソッドを呼び出す。
 
●引数に配列を用いる
 ・メソッドの引数には配列を使うこともできる。
 ・普通の変数をメソッド呼び出しで渡すと…値渡し(call by value
  ・呼び出し元の変数の中身が、呼び出し先の引数にもコピーされる。
  ・呼び出し先の引数の中身を書き換えても、呼び出し元の変数は変化しない。
 ・配列をメソッド呼び出しで渡すと…参照渡し(call by reference)
  ・呼び出し元の配列のアドレスが、呼び出し先の引数にもコピーされる。
  ・呼び出し先で配列の実体を書き換えると、呼び出し元にも影響する。

public class Main {
  // int型配列を受け取り、
  // 配列内の要素すべてに1を加えるメソッド
  public static void incArray(int[] array) {
    for (int i = 0; i < array.length; i++) {
      array[i]++;
    }
  }
  public static void main(String[] args) {
    int[] array = {1, 2, 3};
    incArray(array);
    for (int i : array) {
      System.out.println(i);
    }
  }
}

実行結果
2
3
4

●戻り値に配列を用いる
 ・引数と同様に、戻り値にも配列を使用することができる。
 ・配列そのものを戻しているわけではなく、配列のアドレスを戻している。

コマンドライン引数(command line argument)
 ・プログラム実行時に指定したコマンドライン引数が、JVMによって配列に変換され、mainメソッド起動時に渡される。
  public static void main(String[] args) {
  >java Main 菅原 湊 朝香
  ⇒args[0]:菅原
   args[1]:湊
   args[2]:朝香

スッキリわかるJava入門 第4章 配列(練習問題)

  • 練習4-1
package sample;

public class JavaR04_01 {
    public static void main (String[] args) {
        int[] points = new int[4];
        double[] weights = new double[5];
        boolean[] answers = new boolean[3];
        String[] names = new String[3];
    }
}
  • 練習4-2
package sample;

public class JavaR04_02 {
    public static void main (String[] args) {
        // ①
        // 通常
        int[] moneyList = new int[3];
        moneyList[0] = 121902;
        moneyList[1] = 8302;
        moneyList[2] = 5100;

        // 省略記法
        int[] moneyList1 = new int[]{121902, 8302, 5100};

        // 省略記法
        int[] moneyList2 = {121902, 8302, 5100};


        // ②
        // for文
        System.out.println("for文");
        for (int i = 0 ; i < moneyList.length ; i++) {
            System.out.println(moneyList[i]);
        }

        // ③
        // 拡張for文
        System.out.println("拡張for文");
        for (int money : moneyList) {
            System.out.println(money);
        }
    }
}

  • 練習4-3
package sample;

public class JavaR04_04 {
    public static void main(String[] args) {
        // ①
        int[] numbers = {3, 4, 9};

        // ②
        System.out.println("1桁の数字を入力してください");

        // ③
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        int input = scanner.nextInt();
        scanner.close();

        // ④
        for (int number : numbers) {
            if(number == input) {
                System.out.println("アタリ!");
            }
        }
    }
}

スッキリわかるJava入門 第4章 配列 メモリと変数・配列

第4章 配列 メモリと変数・配列

メモリと変数

  • コンピュータは使用するデータをメモリに記録する。
  • メモリの中は基盤のように区画整理されており、各区画には住所(アドレス)が振られている。
  • 変数を宣言すると、空いている区画(どこが選ばれるか分からない)を変数のために確保する(変数の型によって何区画を使用するかは異なる)。
  • 変数に値を代入する=確保しておいた区画に値を記録すること。


メモリと配列

  • 変数宣言によりint[]型変数が、new演算子により配列の実体(要素の集まり)がメモリ上の区画に作成される。
  • 配列変数には5つの要素まるごとではなく、「最初の要素のアドレス」が代入される。
  • int[ ] score = new int[5]; を実行した時の、メモリ上のようす

 ①int型の要素を5つ持つ配列がメモリ上に作成される。
 ②int[ ]型の配列変数scoreがメモリ上に作成される。
 ③scoreに配列の先頭要素のアドレスが代入される。

  • プログラムからscore[n]と指定されたら

 ①scoreの中に入っている番地(=8832)を取り出し、配列(先頭要素)を見つける。
 ②見つけた配列の先頭要素からn個後ろの要素の区画を読み書きする。

  • 配列変数scoreは「配列の実体は8832番地にあります」と指し示す動作をしている。このことを「参照」と呼ぶ。
  • 参照型(reference type):具体的なデータではなく、メモリ上の番地を代入する変数の事。
  • 基本型:intやbooleanのような具体的なデータを代入する変数の事。