2019年07月16日

ファイル名のクラス(.java)の中には原則、同じ名前のクラス名を記述し、そのクラスにmainメソッドがない場合、Javaアプリケーションをコンソール上で実行できない

この曲カッコいいな。


でもこんな曲が、バスターミナルとか町の先頭とか駄菓子屋とかで流れてたら違和感ありまくりって感じだな。


っていう、まとめもあったように。
そうなんだよな。バスタ新宿に併設してるNeWomanだったか?NEWWOMAN?New Woman?スペル忘れたが。
お土産にしては高いっていうかハイソ過ぎるっていうか、「これじゃない感」は確かに半端ないよな。
東京ソラマチみたいなテナントが入ってたら結構、いい気もするんだけどね。

閑話休題。

本題に入るか、記事のタイトルについて。どういうことかというと…

------------------------------
package dj.shikabane;

public class Underdog {
String musician;
String track;
}

class start {
public static void main(String[] args) {
Underdog music = new Underdog();
music.musician = "Tom Misch";
music.track = "South Of The River";
}

void show(String musician,String track) {
System.out.println("今日聴いた名曲は" + track + "です");
System.out.println("アーティスト名は" + musician + "です");
}
}
------------------------------

このコード、おかしいんだよな。
Eclipse上でコンパイルはできるのに、Javaアプリケーションで実行してコンソールで表示させることができない。
理由を探したところ、


であることが判明した。
ファイル名とクラス名が異なる、mainメソッドのあるクラスがファイル名と異なる、つまり。

------------------------------
package dj.shikabane;

public class start {
String musician;
String track;
}

class Underdog {
public static void main(String[] args) {
start music = new start();
music.musician = "Tom Misch";
music.track = "South Of The River";
}

void show(String musician,String track) {
System.out.println("今日聴いた名曲は" + track + "です");
System.out.println("アーティスト名は" + musician + "です");
}
}
------------------------------

と、ファイル名とmainメソッドのあるクラス名を同一にすれば行けるかと思ったが、publicの箇所で、まだエラーが出る。

------------------------------
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
public 型 start はそれ独自のファイル内に定義されなければなりません

at dj.shikabane.start.(Underdog.java:3)
at dj.shikabane.Underdog.main(Underdog.java:10)
------------------------------

な感じの。
でもJavaアプリケーションで実行することができた。

------------------------------
package dj.shikabane;
class start {
String musician;
String track;
}

public class Underdog {
public static void main(String[] args) {
start music = new start();
music.musician = "Tom Misch";
music.track = "South Of The River";
}

void show(String musician,String track) {
System.out.println("今日聴いた名曲は" + track + "です");
System.out.println("アーティスト名は" + musician + "です");
}

}
------------------------------

maiメソッドのある方のクラスにpublic付けるとエラーが消えた?
これは謎だな…今後、調べよう。
エラーなくコンパイルできるんだけど、結果が何も出力されんかった。
そうか、Underdogクラスでshowメソッドを呼び出してるのに、startクラスにshowメソッドが定義されてないからかな。

------------------------------
package dj.shikabane;
class start {
String musician;
String track;
void show(String musician,String track) {
System.out.println("今日聴いた名曲は" + track + "です");
System.out.println("アーティスト名は" + musician + "です");
}
}
public class Underdog {
public static void main(String[] args) {
start music = new start();
music.musician = "Tom Misch";
music.track = "South Of The River";
}
void show(String musician,String track) {
System.out.println("今日聴いた名曲は" + track + "です");
System.out.println("アーティスト名は" + musician + "です");
}
}
------------------------------

何で同じクラスなのに中身一緒のshowメソッドがある?これでもコンパイルできちゃうってのがおかしいよな。
実行しても、何も出てこないけど。

------------------------------
package dj.shikabane;
class start {
String musician;
String track;
void show() {
System.out.println("今日聴いた名曲は" + track + "です");
System.out.println("アーティスト名は" + musician + "です");
}
}
public class Underdog {
public static void main(String[] args) {
start music = new start();
music.musician = "Tom Misch";
music.track = "South Of The River";
music.show();
}
}
------------------------------

これでオッケー。
セオリー通り、mainメソッドのあるクラスからshowメソッドを呼び出して。
処理の中身は別のクラスに書く感じだ。

さて、今日聴いたTom Misch、かなりいいな。

Tom Misch - South Of The River (Official Audio)

ストリングスの使い方が何かJamiroquaiちょっと思い出したけど、若干違う。アコギとか手拍子とか口笛とか、プリミティブな音色も混じってて、かなり音作りこだわってるな。
ボーカルmainって感じじゃない。ボーカルも音として他の音と調和してる。

Tom Misch - Water Baby (feat. Loyle Carner) (Official Video)

JazzyPianoHipHopだ!氷上でドレッドヘアのcoolな黒人がダンスしてるPVも素敵。
『Geography』 - Tom Misch 買うかな、また。
posted by DJしかばね at 00:31 | Comment(0) | Java学習 | このブログの読者になる | 更新情報をチェックする

2019年07月12日

「非staticフィールドageをstatic参照できません」がよくわからん/「javaにおけるstaticと非staticの判断基準」「静的メンバがインスタンスを生成しなくても利用できるなら、逆にインスタンスを生成することで何が利用できるのか?」も不明

超絶エラー出まくりのコード。

package dj.shikabane;

public class Underdog {
String name;
int age;
}

public static void main(String[] args) {
Underdog underdog1;
underdog1 = new Underdog();
underdog1.name = "負け犬";
underdog1.age = 100;

System.out.println("名前は" + name + "です");
System.out.println("年齢は" + age + "歳です");
}

何でだ?「ネストされた型 Underdog はエンクロージング型を隠せません」は、消すことができたけど。
一行ずつ考えてみた。
まず、

public class Underdog {
String name;
int age;
}

について、ブロックの終わり、最後の’}'でエラーが出ている。
これは何となく、あれじゃねえか。フィールドしかないから、クラスの中に。
恐らく「フィールド(性質)しかないクラスってどうよ?メソッド(機能)も入れてくれ」って話なのか?
いや、でもフィールドだけでも大丈夫だったような…。

package dj.shikabane;

public class Underdog {
static String name;
static int age;

public static void main(String[] args){
Underdog underdog1;
underdog1 = new Underdog();
underdog1.name = "負け犬";
underdog1.age = 100;
System.out.println("名前は" + name + "です");
System.out.println("年齢は" + age + "歳です");
}
}

無理矢理コンパイルした。
ちゃんと結果も出力された。でも、

Open the Java > Compiler > Errors/Warnings preference page and
highlight the problem to configure its severity.
問題: static フィールド Underdog.age には static にアクセスする必要があり
ます

みたいな、×エラーじゃないんだけど、⚠エラーが残る。何か気になる。Underdog.age、じゃねーっつーの。
Underdog1.nameとかUnderdog.ageと、書いてるのに。
もしかして、「Underdog underdog1」みたいに、underdog1っていうクラス型変数?をいちいち用意したせいか。

コンパイルするためになぜか、static付けないといけなくなったのも疑問だ。


で、少しは理解できた。
フィールド及びメソッドの静的メンバには、修飾子staticが付いて、そいつが付いてるメンバはクラスフィールドとかクラスメソッドっていう。
つまるところ、

package dj.shikabane;

public class Underdog {
static String name;
static int age;

public static void main(String[] args) {
Underdog.name = "負け犬";
Underdog.age = 100;
System.out.println("名前は" + name + "です");
System.out.println("年齢は" + age + "歳です");
}
}

だと、コンパイルできたし、問題なくプログラムの結果も出力できた。
クラス型変数underdog1も、ややこしいから消去。

変数nameも変数ageも、別にインスタンスも生成してくても利用できるクラスフィールドだから、普通に使えた。
逆に「インスタンスを生成しないと使用できないインスタンスフィールドとかインスタンスメソッドって何?」って話だ。

それを考える前に、クラスフィールドから呼び出しているコードだけど。
static除くと「非staticフィールドUnderdog.nameをstatic参照できません」とかいうエラーが出てくる。
何このエラー?そもそもjavaにおけるstaticと非staticの判断基準って?

なんていうか、

package dj.shikabane;

public class Underdog {
public static void main(String[] args) {

String name = "負け犬";
int age = 100;

System.out.println("名前は" + name + "です");
System.out.println("年齢は" + age + "歳です");
}
}

でも、別にいいのよ。ちゃんと同じ結果出るし。
しかしこれはすごい単純なコードなんだよな。単にnameとageに値を入れて、出力してるだけだから。
フィールド変数を使用せずにクラス型配列の中身を表示 https://teratail.com/questions/7492 みたいな話があるってことは、べつにフィールドが無くてもいいっていうか。
でもそれはオブジェクト指向プログラミングじゃないから、セオリーじゃないって話か。
すごい簡単なコードなら、別にフィールドに性質とか状態とか属性のデータを入れるためのフィールド変数とか用意しなくても、直接、適当に型だけ指定した変数に値を入れて出力してもいいし。
さらにいえば、変数とか用意せずに、値をそのまんま書いて標準出力してしまえばいいってなる。
でもそれだと、プログラムが複雑になった時に保守性とかが悪くなるから、やっぱり無理にでもフィールドとか使ってみないといけないんだよな。

というわけで、フィールドとかはちゃんと書いて、無理矢理コンパイルしたコード↓

-------------------------------
package dj.shikabane;

public class Underdog {
String name;
int age;

public void main(String[] args){
Underdog underdog1;
underdog1 = new Underdog();
underdog1.name = "負け犬";
underdog1.age = 100;
System.out.println("名前は" + name + "です");
System.out.println("年齢は" + age + "歳です");
}
}
-------------------------------

staticを除いてみた。するとコンパイルはできたのに、実行したらこんなエラーが出た。

エラー: メイン・メソッドがクラスdj.shikabane.Underdogのstaticではありません。次のようにメイン・メソッドを定義してください。
public static void main(String[] args)

何でstaticじゃないといけないの?
ちょっと考える必要あるな。
posted by DJしかばね at 00:40 | Comment(0) | Java学習 | このブログの読者になる | 更新情報をチェックする

2019年06月30日

for文は「for( 初期化式 (initialization); 条件式 (condition); 継続式(increment/decrement) ) { // 処理 }」だけど、for (;;)みたいな無限ループする空のfor文もある

空のfor文は無限ループする http://wisdom.sakura.ne.jp/programming/java/java9.html って話があったんで、試しに動かしてみた。

package dj.shikabane;
public class Roopslider {
public static void main(String args[]) {
int count = 0;
for (;;) {
System.out.print("count = " + count + "\r");
count++;
if (count > 9999) break;
}
System.out.println("ループを抜け出しました");

}
}

forの継続条件とかは、コードブロックの中でも代替できるって話か。

count = 3847
count = 3848
count = 3849

count = 9997
count = 9998
count = 9999
ループを抜け出しました

みたいな結果が出てきたが。
「なんで3847から出てきたのか?」が、意味不明。
面白いのは「 + "\r"」っていうよくわからないコードを省いたら。

count = 0count = 1count = 2count = 3count = 4count = 5count =・・・9997count = 9998count = 9999ループを抜け出しました

と、改行せずに全く違う結果が出てくる。じゃあ\r は何だっていうと。
どうやら改行らしい。


だから改行されないってか、これを省いちゃうと。
たぶん出力結果が3847から出てきたのは、コンソールの最大行数を超えたからだと。
コンソールのバッファー・サイズ(文字)(B)は80000に設定されてた。


を参考に、とりあえず160000、倍にしてみたら。
ちゃんとcount = 0から表示してくれたね。

ちょっと小休止。


で、紹介されているサンプルコードを理解してみる。

package dj.shikabane;
public class Roopslider {
public static void main(String args[]) {
for (int i = 0, j = 10; i < 5 && j > 4; i++) {
System.out.println(i + ", " + j);
j -= 2;
}
}
}

jに入ってる値を−2して、jに代入すればいいってこと。
結果は、

0, 10
1, 8
2, 6

になる。1回目のループでjは10だけど、j -= 2で減算されるから、8になるってか。
2回目のループ、iは1、jは8、また-2されて6に。
3回目のループの終わりで、jは4まで減る。
そうなると「i < 5 && j > 4」っていう条件を満たせないから、4回目は行かずにループ抜けるってか。

はぁ〜今日はこの辺にしとくかな。
posted by DJしかばね at 09:06 | Comment(0) | Java学習 | このブログの読者になる | 更新情報をチェックする
×

この広告は90日以上新しい記事の投稿がないブログに表示されております。