X



トップページ独身男性
660コメント436KB
System.out.println("またJavaの季節がやってきた!" + 2);
■ このスレッドは過去ログ倉庫に格納されています
0001おれさま ◆6CTEZS59O00a
垢版 |
2018/09/13(木) 10:42:14.49
去年の今頃Java学習開始するも挫折
しかし不屈の闘志をめらめらと燃やしながら
そびえ立つ岩壁にいどむため、再びこの地にやってきたのだ!

プログラミング歴は独学Cチョビッツ+独学VBA少々


きょうかしょ
https://www.amazon.co.jp/dp/484433638X
スッキリわかるJava入門 第2版 (スッキリシリーズ)
0157おれさま ◆6CTEZS59O00a
垢版 |
2018/10/12(金) 13:51:28.32
まぁまぁ落ち着いて。
基礎的な動きを確認しながらプログラミング練習してる段階なんでね
これはこうしなければならないみたいなものより
これはこうしても動くし、こうやっても動くみたいな知識が面白いんだよ

javaでGUIってwなんていうけど
メーヴェを作って空を飛ぼうとしてるひとに向かって
空飛ぶならヘリコプターかセスナ使えよ!って言ってるのと同じだよ
ゴールに到達するまでの時間を競うつもりもないし。
プログラミングを仕事にしたらそういう世界になっていくんだろうけど
それってつまんないだろうなと思うんだ
せっかく面白い道具があるのに使い方を縛られるなんてね

>>156
どういうレベルから助言をくれてるのかわからないからどう答えるべきなのか迷うんだけど
まず問題なく動いているということが大事で
今作ったものを土台にいろいろ考えていけるといいなと思ってるよ

https://www.javadrive.jp/tutorial/jframe/index5.html
extends JFrame にかんしてはこれ

>ただし、上記のようにした場合、mainメソッドが含まれるSampleクラスは
>単にmainメソッドが存在するだけのクラスとなってしまいます。その為、
>通常はmainメソッドが含まれるクラスそのものをJFrameクラスの
>サブクラスにする方法が取られます。

このサイトではクラス名はSampleだけど、おれのだとMainのままになってるだけ。
おれはね、これ読んだ瞬間に面白いなぁって思ったんだけど。
自分とこのクラスにextendsして自分とこのmainメソッドで自分のインスタンス生成するとかさ
Swingではこれ普通なの?面白いじゃん
じゃ俺もこれ使おうと思ったんだけどね。
基礎レベルのおれには継承やら実装やらの感覚掴むのに悪くないなって思ってる
ちなみにイベント系のインターフェースも全部Mainに実装させたらMainの行があほみたいに長くなったね
今は匿名クラス使ってるけどね

Runnableも同じようなもんだよ

で、あとsleepか
そもそも起きた問題と何をしたら解決したのかがちゃんとそっちに伝わってるかわからないし
何を問題と捉えて助言をくれているのかもわからないからちょっと難しいよ

もし助言くれるなら、なぜthrd.sleep()だと注意マークがでてThread.sleep()だと出ないのかに
焦点を絞ったもので。引数がどうのこうのの話はそもそもそこが問題の原因ではないだろうと
目星を付けて適当に書いただけで。
問題にしているのはsleepの引数ではなくて、
sleepメソッドがインスタンスから呼び出される場合と
クラスから呼び出される場合の違いなんだ

だれかに何かを伝えるためにここに書いているというよりも
自分が見直した時に参考になる程度にしか書いてないから
いろいろ誤解を与えてるようですまんね

このときはこういう風に考えてたけど、間違ってたなとか、
逆に大事な事忘れてたなとか、あとで見たら面白そうじゃん

>>153
( ^ー゚)b
0158おれさま ◆6CTEZS59O00a
垢版 |
2018/10/12(金) 15:00:32.61
ツールチップで次回取得予定の時刻表示させようとしたけど
右クリメニューとかち合うみたいなんでやめやめ
右クリメニューに表示させるかな
いずれにしてもRun()メソッドがらみなんでちょいめんどくさそう
こんなことやる前に、これまでまとめ上げた内容でもう一度作り直してスッキリさせたほうがいいかもしれん
右クリメニュー関連のコードが迷走してるし
0159おれさま ◆6CTEZS59O00a
垢版 |
2018/10/12(金) 15:04:13.11
あとあれだなぁ
ScheduledExecutorServiceを習得したいね
めんどくさそうだったから、一番簡単な処理方法に逃げてきたんで
0160おれさま ◆6CTEZS59O00a
垢版 |
2018/10/13(土) 05:31:12.81
お天気取得ソフトのエラーがたまに起きるので修正
0時回って5分後に取得しようとすると明日の日付がhtml上にまだ表示されてないようだ
このへん適当にコード書いたんで
日付がないときの分岐処理がなかった
String.containsみたいな処理書くときは忘れないようにしないとな
分岐させないと常にエラーがでるようなものだとすぐに気づくんだけど
たまにしかエラーがでないものだと忘れ去ってしまう

表示されたエラーの内容は半分忘れてしまったんだけど
Stringの配列要素番号として -1 が返されてた
明日の日付が見当たらないと -1 を返してくるようだ
0161おれさま ◆6CTEZS59O00a
垢版 |
2018/10/13(土) 05:59:39.35
いやいや違う

>>160修正
containsは分岐処理でかくものだ
エラーの原因はindexOf()で起きてる
indexOfに渡す引数が見当たらない時にエラーだ
0162おれさま ◆6CTEZS59O00a
垢版 |
2018/10/13(土) 10:54:27.87
ウィンドウのD&D移動で、
MouseListenerの
public void mousePressed(MouseEvent e)での処理なんだけど
いつも間違えるのは、コンポーネントの中での相対座標を取得するコード
JFrameを継承するクラス内だからComponentのメソッドで「も」ある
getX()やgetY()を前置きなしにそのまま使えるんだけど
ComponentのメソッドとしてのgetX()、getY()は相対座標取得のメソッドではない

getX()
コンポーネントの原点の現在のx座標を返します。

なんとなく掴みづらい表現なのだがコンポーネントの左上端の絶対座標を意味してる(と思う)

x = getX(); はダメ。ウィンドウ左上端の絶対座標をとってきてしまう
x = e.getX(); が正解。eを生んだコンポーネントであるJFrameの左上端を原点としたマウスプレス点の座標を取得できる

>>120では、この辺の処理は
pt = e.getPoint();
をつかっており、x と y をばらばらに取得していない
ばらばらに取得するならここで書いたように e.getX()、 e.getY() を使うことになる
0163おれさま ◆6CTEZS59O00a
垢版 |
2018/10/13(土) 15:07:40.61
package privateのクラスをよく使うんだけど
スッキリ入門のどこに書いてあったか探し出せなかったんだけど
やっとみつかったわ
カプセル化のところだ
0165おれさま ◆6CTEZS59O00a
垢版 |
2018/10/14(日) 06:03:39.80
タイトルなしのウィンドウを作り
D&D移動・右クリから閉じる・前回開いた場所で開き直す

こんだけはそらで書けるようにした
いろんな要素が含まれてるから基本覚えるには役に立つ
特にイベント処理は
ActionListener
MouseListener
MouseMotionListener
WindowListener
ComponentListener
が含まれていて練習としては悪くない
Propertyファイルの取り扱いも基礎レベルでしかないけど
しっかり覚えたんで今後に使えそう

またテキストに戻るか
0166おれさま ◆6CTEZS59O00a
垢版 |
2018/10/14(日) 06:12:05.76
Main.class-----------------

public static void Main

class Aaa

class Bbb

---------------------------
これはOK

Xxx.class-------------------

class Aaa

class Bbb

----------------------------
これもOK

クラスはpublicとpackage privateしかない
デフォルトはpackage private
0168おれさま ◆6CTEZS59O00a
垢版 |
2018/10/14(日) 08:41:33.92
iPhoneアプリ作っても実機にいれようとすると年間1万ぐらい払わないといけないと聞いて
作るならandroidアプリだなと思っていたんだけど
よくよく調べてみるとすでに数年前から自分のiPhoneに入れるだけなら無料でいけるようだ
いずれにしてももう少し先の話だ


2. プログラミング言語

アプリを開発する上で最も重要なプログラミング言語。
Androidアプリで主に利用されるのはJavaとC++ですが、
2017年にはオフィシャル言語としてKotlinも追加されました。
iOSアプリは主にobjective-Cが使われますが、
より多くの人がiOSアプリを作れるようにと2014年にSwiftが
オフィシャル言語に追加されています。
0170おれさま ◆6CTEZS59O00a
垢版 |
2018/10/15(月) 12:46:38.43
いいでしょ

Xamarin(「ザマリン」と読みます)は、C#を用いてiOSとAndroidのアプリケーションを
開発するためのライブラリおよび開発環境です。
XamarinはMicrosoftよりVisual Studioの一部として提供されています
0171おれさま ◆6CTEZS59O00a
垢版 |
2018/10/15(月) 12:58:20.37
●iOSアプリ
プログラミング言語 Objective-C Swift
開発環境 Xcode
開発に使用するOS Mac

●Androidアプリ
プログラミング言語 Java
開発環境 Android Studio Eclipse
開発に使用するOS Windows Mac



Xamarin

プログラミング言語 C#
開発環境 Visual Studio(Windows)もしくは Xamarin Studio(Mac)
開発に使用するOS Windows Mac

Windows上では、Visual Studioという非常に優れた開発環境を
利用してiOS/Androidアプリを開発することができます
(注: 詳しくは後述しますがiOSアプリをビルドするには別途Macが必要になります)。




って結局Macいるってことかいな
さすがに無理ですわ
0172おれさま ◆6CTEZS59O00a
垢版 |
2018/10/15(月) 17:05:33.63
abstractクラスを継承したときに、
abstractなメソッドをオーバーライドして確定することを
「実装する」と表現する

これが「実装」という言葉の基本

インターフェースを実装するというのは
インターフェースに含まれるabstractなメソッドをオーバーライドして確定するからこそ
こういう表現が使われる
0173おれさま ◆6CTEZS59O00a
垢版 |
2018/10/15(月) 17:10:34.45
eclipseでかき込んだメソッドやクラスにカーソルを合わせてから
F3を押すとそのメソッドやクラスの宣言が表示される 中身をみられる
F4を押すと階層構造をみることができる
0175おれさま ◆6CTEZS59O00a
垢版 |
2018/10/17(水) 07:55:17.33
オラクルの決定以後、Java周りはざわざわしてて
おれもこの先どうするか考えつつ勉強してる

とりあえず実践編読み終わってからちゃんと決めようとは思ってるが
できたら実践編の次にある2冊を読みたい
Javaそのものの勉強に限らず、サーバやらデータベースやら、
この辺の一般的な知識を頭に入れるいい機会なんじゃないかと思う
他の言語に行くのはいいんだけど、また一からやったら深い所に行くまでにまた時間かかってしまう
言語の勉強だけにいつまでも時間費やせないんで、選択に迷うところだ

すでにJavaScript、C#、pythonの入門本は買ってあるんで
ちょいちょい浮気しながら様子を見ていこうと思ってる
0177おれさま ◆6CTEZS59O00a
垢版 |
2018/10/18(木) 14:47:45.14
ZonedDateTimeは実践編で紹介されていたのか
この辺の新しい日付の処理方法は便利だな

newできないものが多いから注意か

既に作ったプログラムで
DateとThreadを使っているものがあるんだけど
正しく動作しないことがあると書いてある
ふむむ
0181Mr.名無しさん
垢版 |
2018/10/20(土) 03:48:27.50
eclipseでimport文いれるのがめんどくさくなってきた
マウスをクラス名に合わせてポップアップから選択してたんだけど
もっと簡単な方法があるはずだと思ってしらべてみた

まず、* を使って省略して一気にimportすることにした
ウィンドウ→設定→Java→コードスタイル→インポートの編成
.*に必要なインポート数
これが99になってたので1にする

インポートの追加([Ctrl] + [Shift] + [M]) 1個ずつimport
インポートの編成([Ctrl] + [Shift] + [O]) 一気に全部import

これでずっと楽になるはず
0183おれさま ◆6CTEZS59O00a
垢版 |
2018/10/20(土) 13:58:19.34
空白を示す正規表現に \s というものがある
これをこうやって使ってみるとエラーがでる
boolean b = "abc def".contains("\s");

これだとエラーがでない
boolean b = "abc def".contains("\\s");

ここに理由が書いてあった
https://teratail.com/questions/31841


が、\n だと \\n にしないでも動く
理由の解明は後回しにすることにする
とりあえず正規表現で \\ としないと駄目なことがあるということで。
0184Mr.名無しさん
垢版 |
2018/10/20(土) 14:08:51.80
典型的な本読んだだけで理解したつもりになってるタイプだな
入門編読み終わったんならオブジェクト指向で簡単なアプリで作ったら?
DBの代わりにファイルに読み書きするToDoリストやクリックすると月が替わるGUIカレンダーとか
本当に理解してるならこのくらい簡単に作れるはず
それもできないのに正規表現やThreat知っても成長しないぞ
0186おれさま ◆6CTEZS59O00a
垢版 |
2018/10/20(土) 15:52:45.04
インプットとアウトプットは両方大事だね
これはどんな勉強にも言える

入門編読んでから
4つ作って常時起動してるPCでずっと動かしてる
もちろん入門テキストの知識だけでは作れないものなので
いろんなサイト巡って知識かき集めて作ってある

今やってるというか、つい最近までやっていた作業は
最後に作ったプログラムから自分が気に入った機能を実現するコードを抜き出して
雑だったものをもう少ししっかりしたものに組み直す
こんな風にしてお手本コードとしていくつか作っておく
そして、こいつらを何も見ずにざっと書けるようにする
書くたびに所々アレンジを加えていろいろ試して見る
ということをやってた
一つが大体300行程度のコードか

これは結構楽しい
ベースとなるコードは毎日同じなんだけど、理解が深まって悪くない

正規表現はずっと昔からいろんな所で使ってきたんだけど
もちろんプログラミング始める前の話ではある。
覚えようと思ってはいたんだけど、使う機会が年に数回であとはコピペでいけちゃって
なんとなくうやむやにしてて、しっかり頭に入れてなかった
なんというか、正規表現には思い入れがあって、是非自分のものにしたいなぁと。
ちょいちょい毎日のアレンジに組み込んで使っているのだ

数日前からはテキストを読み進めている
アウトプットは楽しいけど、インプットも進めないと知識の幅が広がらない
スカスカな知識でもいいから、こういう事ができるんだということをなんとなく覚えていると
アウトプットとしてソフトを作っているときに選択肢が広がる
0187Mr.名無しさん
垢版 |
2018/10/20(土) 16:11:20.02
具体的にどんなアプリ作ったんだ?
もしかして>>160みたいなの?
0188おれさま ◆6CTEZS59O00a
垢版 |
2018/10/20(土) 16:34:18.61
ちなみにカレンダーはそのうち作ろうと思っている
上のほうですでに書いたんだけど、今デスクトップ上で表示してるカレンダーが
日本の祝日や振替休日を正確に示していないので、代用品が欲しい。
その辺から拾ってこれば早いんだけどそれじゃなんだし。

ところで、プログラムを作ってて思うのは、自作のクラスの
インスタンスを何個も作って活用するという場面はなかなか出くわさないということ。
いや、正確にいうと、そういう場面に無理やり持っていくこともできるんだけど、
無理してる感がすごくて、不自然すぎる

毎日アレンジ練習でプロパティファイルReaderクラスを作って遊んでたりする
カプセル化を施すためにフィールドをprivateにしてsetter、getterを作って
setterにはフィルターかけたりなんかするわけだけど、今までつくったような小規模ソフトだと
ここまでやっても、おいおい無理スンナよ・・・という天の声が聞こえてくる
多様性の練習でabstractクラスやinterfaceをいくつも作るのは面白い
最後にforでまわして結果がでるとすっきりする
が、練習でしかない

その点、カレンダーは日付クラスを作ると大量にインスタンス生成できたりなんかして面白そうだ
月クラスや年クラスなんかも組み込んじゃって多重構造にしちゃったりとかいろいろ想像してる
祝日やらの情報は内閣府のcsvを自動で取り込んで組み込んでもいい
おそらく今の知識で足りるだろう

じゃ、なんで作ってないのかというと、実践編の知識を組み込みたいと思ったからだ
組み込んだほうがよりコード的に面白そうなのがつくれるのであれば、だけど。
今日はコレクションの章を読んだんだけど、この辺も使えそうなら使ってみるつもりだ
日付という集合はキッチリカッチリ仕様が固まっているものなので、
曖昧さが残るデータを取り扱うのに便利そうなコレクションの知識は使えないかもしれないが。

もう一点カレンダーを作るのを遅らせている理由
今の知識だとThreadクラスに定期実行の役割を担わせていくしかない
でもThreadクラスはいろいろと問題があるようだ
既にPCで動かしている4つのソフトはどれもThreadクラスを使っていて
これ以上そういうソフトを増やすことでPCを不安定リスクに晒したくないというのがある。

これについては問題があって、ざっと見る限り実践編では解決する手段が書かれていない
ネットを漁るか別のテキストに手を伸ばすか、という話になる
コピペして流用するのは簡単だ
でも使うならコピペではなく、ちゃんと理解した上で使いたい
代用となるクラスについては上の方でも何度か書いているが
イマイチ自分の理解が浅い部分がある
この辺の理解が深まった頃にカレンダーを作るかもしれない

そう急ぐものではない
0189Mr.名無しさん
垢版 |
2018/10/20(土) 17:54:53.93
俺も入門書読んでた頃、カレンダーアプリ作ったことある

俺はMVCモデルで、viewはSwingで年月変更するボタンと7×6個のJTextFieldを用意して、そこにmodelとなる二次元配列で作った日付をcontrollerではめ込んでいくって設計にした
でも、日付の始まりは月によって違うし祝日は年によって日付が変わるからそこら辺の調整が結構悩んだな
頭で理解するのと、実際にオリジナルのアプリを作るのでは全然違うことを知った

いきなりThreat使ったアプリなんて作れるわけないんだから、まずは簡単な設計でオブジェクト指向に則ったちゃんと機能するアプリを作ってはどうよ?
0190おれさま ◆6CTEZS59O00a
垢版 |
2018/10/20(土) 18:45:27.82
兄さん、それThreatじゃなくてThreadっすよ
何度も間違えてるところからして使ったことないんだろうけど・・・・
おれの作ったアプリは全てThreadクラス利用した定期実行プログラム

兄さん・・・・

おれVBAやってたんだけど
やり始めて数ヶ月後にカレンダーをクラスモジュールとform使って作った
クリックすれば月がどんどん変っていくやつ
日付をクリックすることでその日付が起点となってエクセルの表に入っていく
おれにとってカレンダーを作る事自体はそう難しくないんだよ
VBAみたいなオブジェクト指向でない言語でクラスモジュール使って書く方がよっぽど難しいんだ・・・

てかね、そんな競争みたいのどうでもいいんだ
なんで言語やってると後ろから蹴り飛ばしながらお前のあれが悪いこれが悪いの
言う人多いんだろうか
楽しんでやろうよ?ね?
0191Mr.名無しさん
垢版 |
2018/10/20(土) 20:16:39.60
予測変換使ってたから間違い気づかんかったw

VBAってExcelのマクロを組んだってことでしょ?
そうじゃなくて一からアプリを作ったことあるのかってこと

雑学で本読んでるだけならどうでもいいけど、本気でプログラミングを学びたいなら方向が間違ってるってアドバイスしてるだけ
0193おれさま ◆6CTEZS59O00a
垢版 |
2018/10/21(日) 08:59:11.44
ArrayListのインスタンスが変更されると発生する例外
ConcurrentModificationException

いろいろと書いてみるとたまに出る
iteratorを使って回してると出た
iterator宣言文をちょい上の方に書いてしまうと出るようだ
whileの直前にしたら出ない

どうやらArrayListにaddする前にiteratorをArrayListを対象に宣言してしまうとでるみたいだ
addし終わってからwhileで回す直前にいれるようにしよう
0195おれさま ◆6CTEZS59O00a
垢版 |
2018/10/21(日) 15:19:05.05
実践編はなかなか重いな
重要なコードはそらで書けるようにしていこう
曖昧なままだと先に進んだところでつまずく
とかいいつつ、どれがほんまもんに大事なコードなのかは先に進まないと分からないのだが

一応ArrayListとHashMapの操作法は基本的な部分は頭にいれた
ジェネリスクについてより深くやっていくようなのでちょうどよかった
0198おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 06:57:09.49
public static final String LS = System.lineSeparator();

改行 定数

今度からこれを使う事にする



旧版
public static final String LS = System.getProperty("line.separator");
0199おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 10:09:45.11
継承関係
B a t t l e C r e a t u r e
↑            ↑
Character       Monster
↑    ↑       ↑
Hero Wizard     Slime

多様性の話
List<Character> alChar = new ArrayList<Character>();
Character c0 = new Hero("勇者あ");
Character c1 = new Hero("勇者い");
Character c2 = new Hero("勇者う");
Character c3 = new Hero("勇者え");
Character c4 = new Hero("勇者お");
Character c5 = new Wizard("魔法使いa");
Character c6 = new Wizard("魔法使いb");
Character c7 = new Wizard("魔法使いc");
alChar.add(c0);
alChar.add(c1);
alChar.add(c2);
alChar.add(c3);
alChar.add(c4);
alChar.add(c5);
alChar.add(c6);
alChar.add(c7);

List<Monster> alMons = new ArrayList<Monster>();
Monster m0 = new Slime('A');
Monster m1 = new Slime('B');
Monster m2 = new Slime('C');
alMons.add(m0);
alMons.add(m1);
alMons.add(m2);

List<BattleCreature> alBC = new ArrayList<BattleCreature>();
alBC.add(c0);
alBC.add(c1);
alBC.add(c2);
alBC.add(c3);
alBC.add(c4);
alBC.add(c5);
alBC.add(c6);
alBC.add(c7);
alBC.add(m0);
alBC.add(m1);
alBC.add(m2);

for (BattleCreature bc : alBC) {
 System.out.println(bc.getClass());
}

こうやってクラス名を取得したときにBattleCreatureではなく
中身のHero、Wizard、Slimeを表示出来ないかと思って試して見たんだけど成功
0200おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 10:23:06.11
for (BattleCreature bc : alBC) {
 System.out.println(bc.getClass().isInstance(c0);
}

とすることでBattleCreatureの中身がCharacterかどうかをbooleanで戻す事ができる
c0としてあるが、これはCharacter変数であればなんでもいい
要は、Character変数に代入できるかどうかを判定してくれてる
0201おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 10:24:50.00
と思ったが違うわ
c0の中身がHeroだから
Heroかどうかしか判定してくれてないな

ん〜失敗
0202おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 12:36:38.25
どちらか全滅までの自動バトルプログラム完成

魔法使いカンの攻撃!
スライムAに14のダメージを与えた!(186)
スライムCの攻撃!
魔法使いトンは53のダメージをうけた!(0)
魔法使いトンは死んでしまった!
勇者ぽんの攻撃!
スライムBに0のダメージを与えた!(200)
スライムCの攻撃!
勇者ぽんは64のダメージをうけた!(36)
魔法使いコンの攻撃!
スライムBに42のダメージを与えた!(158)
魔法使いカンの攻撃!
スライムBに16のダメージを与えた!(142)
スライムCの攻撃!
魔法使いカンは127のダメージをうけた!(0)
魔法使いカンは死んでしまった!
勇者ぽんの攻撃!
スライムBに140のダメージを与えた!(2)
魔法使いコンの攻撃!
スライムBに22のダメージを与えた!(0)
スライムBを倒した!
スライムAの攻撃!
魔法使いコンは52のダメージをうけた!(0)
魔法使いコンは死んでしまった!
スライムCの攻撃!
勇者ぽんは21のダメージをうけた!(15)
勇者ぽんは逃げ出した!
勇者ぽんたちは、ぜんめつしてしまった!
0205おれさま ◆6CTEZS59O00a
垢版 |
2018/10/23(火) 13:12:01.82
WHSをずっとやってた
簡単なコードおぼえた
フォルダ作ったりファイルコピーしたり。
Javaと比べると簡単
0207おれさま ◆6CTEZS59O00a
垢版 |
2018/10/24(水) 15:52:11.45
今日は復習だけ

WSHのコード2つ
実践編のコード3つ

これだけ

実践編のジェネリクスと列挙型の練習問題、金庫にアイテム出し入れするやつ
最初見たとき一体これはなにやってんだと思ったけど、
いろいろやってたら理解できた

・自作のジェネリクス付きのクラスを使う事でいろんな型のインスタンスをを金庫に入れることができるようにする

・次に、金庫を守るためにカギとなる仕組みを作る
ここで列挙型を利用する
久しぶりのswitchがでてきて復習になった

switch (keytype) {
case LOCK :
 break;
case FINGER :
 break;
}

2つを分離して考えないといけない
0209おれさま ◆6CTEZS59O00a
垢版 |
2018/10/24(水) 16:07:34.72
実践編は各章の練習問題を解けるようにすることを目標とする
解けるというか、覚えて利用出来るようにしておく
これだけだと、テキストに書いてあることの一部しかカバーできない
でも、実践編では、最低限の重要な知識を抑えることに焦点を絞ることにする

toStringのオーバーライドとかクソつまらなさそうなのは切って捨てたいけどどうすっか
この辺は自分で使うイメージが全くわかない
コレクションのところで自然順序とかなんとかでこの辺のオーバーライドがされてないと
ダメだと説教されたんで、大事なんだろうけど

とにかく最後までなんとか読み切る
0210おれさま ◆6CTEZS59O00a
垢版 |
2018/10/24(水) 16:10:44.57
Javaでは型安全、型安全で列挙型やらやってるんだけど
WSHは変数宣言いらないわ全部Variantだわで適当もいいところだ
楽だけど
0211おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 05:49:23.98
復習復習復習

Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, get(Calendar.DAY_OF_MONTH) + 100);

のように書くと、c の日付は +100 される
これと比較したいのはLocalDateTimeクラスを使ったパターン↓

LocalDateTime ldt = LocalDateTime.now();
ldt.plusDays(100);

これだと ldt の日付は +100 されない
plusDays()をCalendarクラスのset()と同じような感覚で書くと間違える

plusDays()は戻り値がLocalDateTimeオブジェクト→オブジェクト変数に格納必要
set()は戻り値がvoid→変数への格納不要

正解は、2行目を
ldt = ldt.plusDays(100);
とすることで100日加算されたオブジェクトに置換える必要がある
0212おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 05:55:24.37
同じような間違いとして

SimpleDateFormat sdf = new SimpleDateFormat("西暦yyyy年MM月dd日");
System.out.println(sdf.format(c.set(Calendar.DAY_OF_MONTH, get(Calendar.DAY_OF_MONTH) + 100).getTime()));

とするとエラー
原因は set() の戻り値をCalendarオブジェクトと勘違いしている点
もしそうであれば
c.set().getTime()
によってDateオブジェクトを取得できる
しかし
c.set()
はvoidである
よって、これにgetTime()をつなげることはそもそもできない
0213おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 05:56:40.40
もう何度もやってるからわかってるわいと思ってアレンジして書くといろいろと問題が起きる
細かい部分が分かってないことがアレンジによって露呈する
0214おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 06:01:38.39
そういえばすっきり入門の最初の方でこういうのを書いていた

String s = new java.util.Scanner(System.in).nextLine();

理屈はいいから覚えろみたいなことが書いてあったんだけど
覚え直した方が逆に楽になりそうだ

Scanner sc = new Scanner();
String s = sc.nextLine();

単純にScannerクラスのインスタンス生成して
nextLine()を呼び出しているだけ
importは別途必要だ
0215おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 10:20:29.41
ディープクローンが難しかった
テキストと同じ形式なら理解できたんだけど
少し違った形にすると突然難しくなる

ディープクローンの必要性がある変数がprivateで
さらに、コンストラクタの引数になっているような場合

やっと練習用雛形作れたから何度も書いて理解していこうと思う

equalsやhashCodeその他のオーバーライドも組み込んだから
この辺の復習として使う
結局この辺はコレクション関連分野でもあるんで
コレクションの復習にもなる
0216おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 03:59:48.27
>>183について

\n

\s

この2つはそもそも種類が違う
\n は改行で、\s は空白だから違うのは当たり前とかそういう意味じゃない
属しているグループが全然違う
\n は \t \r などと同じ「エスケープシーケンス」
\s は \w \d などと同じ「あらかじめ定義されている文字クラス」

\n

" " の中にそのまま書いただけで \n という文字そのものではなく、
「改行」として認識される

\s

" " の中に書いたときに 「 \s という文字列として認識」 された場合に
初めて特殊な意味、ここでは「空白」として認識される

もう少し詳しく書く

"\s" と書いてしまうと、\ を特殊な記号として認識してしまう
そのため、これはエスケープシーケンスの一種だな、と誤解してしまう
しかしエスケープシーケンスには \s は存在しないため、エラーとなる

「 \s という文字列として認識」 させるには \ がもつ特殊な機能を消し去って
\ そのままの文字列として認識させる必要がある
そこで、\ の前にもう一つエスケープのための \ をつける
こうすることで、 「 \s という文字列として認識」 してもらえる

つまり、あらかじめ定義された文字列を matches などで使う時は、総じて \\s \\d \\w
のような書き方をしなければならないということになる
0217おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 04:01:51.70
>>216
修正

つまり、あらかじめ定義された文字列を matches などで使う時は、

つまり、あらかじめ定義された文字クラスを matches などで使う時は、
0218おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 04:14:51.67
>>183の中に書いてあるURL
ここで質問している人は、おれと同じように、
\n のようなエスケープシーケンスと混同したのだと思う

回答にはエスケープシーケンスとの違いが説明しているものがない
質問した本人は分かったつもりでいるみたいだけど、
問題は解決できてないんじゃないかと思う

スッキリ実践編にもその辺を書いてくれるとよかったな
0219おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 05:11:57.84
ここで疑問がもう一つ生まれる

\s が 「 \s という文字列として認識」 されたときに初めて 「空白」 と捉えてもらえる
それならば、
\s という文字列とマッチするかどうかを調べたいときはどうすんぢゃい と。

String s1 = "\\s";
System.out.println(s1);
if (s1.matches("\\s")) {
 System.out.println("s1 ok");
}

これではokはでない
s1 は \s と認識されているが
matches("\\s") の \\s は 「空白」 として認識されてしまうためマッチしない
\s と書くとエラーでるし。

今後の課題として残しておこう
0221おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 05:32:20.22
>>219

String s1 = "\\s";
System.out.println(s1);
if (s1.equals("\\s")) {
 System.out.println("s1 ok");
}

これで一応おk
要は s1 で \s と認識できたわけだから
同じようなレベルで認識してもらえるようなメソッドを使えばよいだけ
そもそもmatchesでは不可能なのかもしれない

containsでもいけた
0222おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 06:27:50.57
C#関連(本買っただけで何もやってないが)

ビルドの中にコンパイルがある。

コンパイル:
コンピュータが実行するのに適した形式に変えて、実行可能なファイルに変換する。

ビルド:
コンパイル+使っているライブラリに関連づける(リンク)

https://qiita.com/rico/items/9ab8aa110e757a13ef37


Visual Studio が無い Windows 環境で c# コードをコンパイルする
https://qiita.com/asterisk9101/items/4f0e8da6d1e2e9df8e14
0223おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 06:34:16.89
スクリプト

簡易的なプログラムのこと。スクリプトを記述するための言語をスクリプト言語といい
、機械語への翻訳を必要とせずに実行できる。スクリプト言語は、
アプリケーション開発用の本格的なプログラミング言語に比べ、
用途を限定することで、覚えやすいように簡単な構造になっている。
代表的なスクリプト言語としては、JavaScript、PHP、Perlなどがあり、
特定のアプリケーションの動作の記述、マクロやバッチファイルの作成、
CGIなどの簡単なプログラムに用いられる。
https://kotobank.jp/word/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88-4871


最近使ってるVBSもスクリプト言語
0225おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 08:30:31.85
public class Book {
 public boolean equals(Object o) {
  if (o == this) return true;
  if (o == null) return false;
  if (!(o instanceof this)) return false;//←ここダメ
 }
}

A instanceof B

「参照型変数a が bクラス/インターフェース/配列のインスタンスかどうか」
を調べるものなので
Bにインスタンスを持ってきてはダメ

Bに来るのはこの場合だとクラス名のBook

if (!(o instanceof Book)) return false;

が正解
0227Mr.名無しさん
垢版 |
2018/10/29(月) 02:05:19.26
>>219
正規表現で\sという文字列を表すにはエスケープして\\sとなる
だがこれをそのまま引数に渡すとJVMが最初の\を文字エスケープと認識して\sという文字列に変換し、結果的に正規表現の空白文字にマッチするか検証することになる
\\sという文字列を正規表現として渡すには文字エスケープが2つ付けて、\\\\sとする必要がある
0228おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 11:11:41.30
>>227
なるほどねぇ
言われてみればそうだな

String s = "\\s";
System.out.println(s);

if (s.matches("\\\\s")) {
System.out.println("ok");
}


ちなみにだけど、>>227の前半部分の説明を \n についてすると?
0229おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 11:13:40.08
ラムダ式とかの6章クリア
練習問題とstream()の基本的な使い方ぐらいだけど、まぁいいか

ぐぐるとラムダ式使ってるコードってたまに出てくるから
参考にしたいときに使える知識かなとは思う
0230おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 15:29:01.06
ProcessBuilder pb = new ProcessBuilder(
    "c:\\windows\\system32\\notepad.exe", "calcreport.txt");

ProcessBuilder pb = new ProcessBuilder("java", clazz.getName() );

こいつら、上が第7章198ページ、下が同じく第7章217ページ練習問題の答

上が本文内で出てきたときは、まぁこんな感じで外部のexe起動できるんだな
ああそうですか、で終わった

練習問題で下のが出てきて???????????????ですわ
一応練習問題はできるようにするという目標を立てているので、しゃーないから調べてみた

意外と簡単だった

つまりだ、
●CMDでなんかプログラムを起動するときに
>xxx yy zz
みたいに打ちこんでEnterパーン!てやるとする
ちなみにxxxはexeだったりいろいろ

●これをJavaから同じように起動したいと思うなら
ProcessBuilder pb = new ProcessBuilder("xxx", "yy", "zz");
pb.start();

具体的に書くと
●CMD
>notepad /W test.txt
●Java
ProcessBuilder pb = new ProcessBuilder("notepad", "/W", "test.txt");
pb.start();

CMDでnotepadのかわりにnotepad.exeとしてもいいのだが
これはJavaのほうでも同じで "notepad" のかわりに "notepad.exe" としてもよい
ちなみにメモ帳はパスが通ってるからCMDにおけるカレントフォルダがどこであっても
notepad.exeへの完全なパスなしで起動できる

ProcessBuilderの第一引数においても同様に絶対パスを書く必要はない
とにかくCMDでどう書くのかを参考にして書けばいいだけ

よって上に書いた1個目のProcessBuilderの宣言で
ProcessBuilder pb = new ProcessBuilder("notepad.exe", "calcreport.txt");
と書いてもいける

ただし、違いが一つある
CMDだとcalcreport.txtがカレントフォルダになければ新しく作りますか?
とのウィンドウがでる
Javaではcalcreport.txtが存在しないとエラーが生じる

2つ目の
ProcessBuilder pb = new ProcessBuilder("java", clazz.getName() );
も同様
CMDでFQCNを使ってclassファイルを実行する場合に
>java jp.co.aaa.Calc
としてEnterパーン!とするなら
Javaでは
ProcessBuilder pb = new ProcessBuilder("java", "jp.co.aaa.Calc");
pb.start();
と書く
第二引数が clazz.getName() となっているのはFQCNを取得するためだ 👀
Rock54: Caution(BBR-MD5:1341adc37120578f18dba9451e6c8c3b)
0231おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 16:30:53.48
>>230の2つ目を考えるにあたって注意しなければならないこと

あくまでも ProcessBuilder は「外部」プログラムの実行に使われる
よって、
Javaのクラスファイルを実行するといっても、
外部に存在しているコンパイル済のクラスファイルの実行に使うであって
今現在組んでいるソースコードに存在する他のクラスを指定してもダメ

コードが正常に動くか実験したい時に勘違いしないようにする
0232おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 16:44:08.02
Eclipseで楽してたらコマンドラインから実行する方法忘れてしまった

例:
Main.class
-----------------------
package aaa;

public class Main {
 public static void main(String[] args) {
  System.out.println("test");
 }
}
-----------------------

(パスを通さないことを前提に説明・カレントフォルダ名はtestとする)
これをコマンドラインから起動するときは
フォルダtestの中にフォルダaaaを作る
その中にMain.classを入れておく
propertiesファイルとか使うなら
フォルダtestに入れておく
CMDでフォルダtestに移ってから
>java aaa.Main
で起動

eclipseのワークスペースからクラスファイルを拾ってくる時は
binフォルダの中をみればいい
ただ、この中にMain.classとは異なる見慣れないものが入ってたりする
Main$1.class
Main$2.class
Main$3.class

eclipseがバックアップ用に用意したものかと思ってフォルダaaaにコピペしなかったらエラー
表示をみるとどうやらこいつらも必要なようだ
この3つもaaaに放り込んだらうまく起動した
0234おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 16:51:03.00
ここつまんねぇなぁ
覚えても意味なさそうだぁ
とか思っててもいざ練習問題ちゃんと出来るようにしようとすると
派生的にいろんな所の復習することになる
この 「いろんな所」 が結構大事な分野だったりするんで
結局がんばってやったほうがいいんだろうな
0235おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 10:33:26.15
よし、ProcessBuilderによるclassファイル実行でけた

eclipseの今扱っているプロジェクトのプロジェクトフォルダの直下に
フォルダaaaをおいてこの中にMain.classを入れる

ProcessBuilder pb = new ProcessBuilder("java", "aaa.Main");
pb.start();

で起動確認済
0236おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 11:14:46.84
>>235の状況下で

Class<?> c = Class.forName("aaa.Main");
System.out.println(c.getName());

はできなかった
ProcessBuilderではいけるのになぜだ

もしかしてと思いながらbinフォルダの中にaaaフォルダをぶちこんだら行けてしまった
手法がどうであれ、ClassクラスもProcessBuilderと同様に外部のクラスファイルに
アクセスできるようだ
0237おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 12:48:17.63
eclipseでコマンドライン引数を渡して実行する方法

実行の構成→「引数」タブ→プログラムの引数

ここにコマンドライン引数を並べればいいだけ
0238おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 12:59:51.70
>>236はちと違う感じがする
クラスファイルへのアクセスってのは内部も外部もないのでは。
この辺は学習が進めばハッキリしてくるだろう
0239おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 13:38:32.43
7章の練習問題は解答が間違えてるようだ
https://teratail.com/questions/153338

問題の指示によると、
文字列配列を引数とするmainメソッドの存在を確認しなければならない
存在する場合のみ、第二引数による条件分岐に入る

にもかかわらず、
@条件分岐に入ってから存在確認処理をしているのが第二引数が I のケース
Aそもそも存在確認を行ってさえいないのが第二引数が E のケース

@の存在確認とは、
getMethod()によって 文字列配列が引数であるmainメソッドを指定している
この条件に当てはまるメソッドがない場合に例外が投げられるようになってる
(throws Exception)
例外はメソッドを呼び出したmainメソッドで処理される
という部分を指している
0240おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 15:06:42.90
>>239の間違いを正したコードを書いてた

これでいいだろと思って実行してみるんだけど
ProcessBuilder による起動がうまくいかない
起動するクラスのmainメソッドには

System.out.println("eating memory.......");

と書いてあるのだが、これが表示されない
ProcessBuilderによるクラス実行は実験済で間違いないはずなのだが
いろいろやっても上コメントが表示されない

まさかな、と思ってこれを実行するクラスのmainメソッドに追加

JFrame jf = new JFrame();
jf.setSize(100, 100);
jf.setVisible(true);

そしたらなんとフレームが出現するじゃないか
ProcessBuilderによる実行は、「外部プログラム」の実行なので、printlnがあっても
内部的な処理結果を表示するコンソール画面には出ないということか

ちなみに実行するクラスファイルはbinフォルダに置いたままではだめ
プロジェクトのフォルダ直下に置く
ProcessBuilderによる実行は、やはり「外部のプログラム」を動かすものなので
eclipse上、カレントフォルダはプロジェクトのフォルダ直下(この辺は不確実)
0242おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 15:12:25.80
ちなみにリフレクションによる実行では
ちゃんとコンソールにprintlnの内容が表示される
これが
External Launch と
Internal Launch の違いってことかな
0243おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 15:46:01.03
>>238の続きなんだけど、リフレクションによる実行は「内部」だね
>>236で、binフォルダにaaaをぶち込むと実行できたのは
まさにbinフォルダが内部的なものだからだ
普通にクラスのソースコードを書いて実行するとbinフォルダにクラスファイルが生成される
つまり、binフォルダにクラスファイルを置くということは、
ソースコードに書いたのと結果的に同じ
外部のクラスファイルを持ってきたという考えはしない方がいい
0244おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 13:56:32.92
>>239の問題をクリア

@で使っている例外を利用してmainメソッドの存在確認をする方法は
秀逸だと思うので、これはちゃんと利用する
ただし、
launchInternalメソッドの中に書くのではなく
mainメソッドに書く

---------------------------------------------
try {
 m = c.getDeclaredMethod("main", String[].class);
} catch (NoSuchMethodException e) {
 System.out.println("指定されたメソッドが存在しません。");
 System.exit(1);
}
-----------------------------------------------
m は static なクラス変数として宣言したMethodクラスのインスタンス変数
クラス変数としたのは launchInternalメソッドにおいて invoke するのに流用するため

あと、launchExternal メソッドで起動した場合に起動確認のためJFrameを表示させたい
そこでMemoryEaterクラスの main メソッドの中にJFrame表示のコードを入れた
さらにフレームタイトルに launchInternal、 launchExternal どちらから起動されたか
わかるように I か E の文字をいれることにする
そのため、これらのメソッドを起動する際に、I か E の引数を渡すことにする
内部起動か外部起動かによって引数の渡し方が違ってくるところがポイント
-------------------------------------------------------------
public static void launchExternal(Class<?> clazz) throws Exception {
 ProcessBuilder pb = new ProcessBuilder("java", clazz.getName(), "E");
 Process proc = pb.start();
 proc.waitFor();
}
public static void launchInternal(Class<?> clazz) throws Exception {
 String[] args = {"I"};
 m.invoke(null, (Object)args);
}
--------------------------------------------------------------
0245おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 15:24:10.35
この問題は例外処理の復習になる

●例外インスタンスを自分で投げるケース
throw new IllegalArgumentException("起動方法の指定が不正です");

IllegalArgumentExceptionはメソッドの引数が不正

●例外を伝播させる
public static void launchExternal(Class<?> c) throws Exception { }

throws と複数になってるところがポイント

●例外処理中の e.getMessage() とは
これは e.printStackTrace() を使った場合に表示されるメッセージが冗長なため、
これらのメッセージのうち一部分だけを表示させたいときに使うようだ
具体的には、今取り組んでるコードにおいて、実行対象となるクラスにmainメソッドがない場合

もし e.printStackTrace() なら
-----------------------------
java.lang.NoSuchMethodException: MemoryEater.main([Ljava.lang.String;)
 at java.lang.Class.getMethod(Class.java:1786)
 at Main.main(Main.java:19)
------------------------------

もし System.out.println(e.getMessage()); なら
------------------------------
MemoryEater.main([Ljava.lang.String;)
------------------------------

調べた結果このようになったのだが、疑問に感じたのは実践編7章解答で
catchの中にこのような記述がある

System.out.println(e.getMessage());
e.printStackTrace();

包含関係にあるこの2つを並べることに何の意味があるのか分からない
今のところは自分が調べた結果を信じることにしておこう
e.getMessage()はエラーメッセージを簡潔に書きたいときに使うもの、とする
0246おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 16:06:25.26
あとこれ

Method m = clazz.getMethod("main", String[].class);

getMethodメソッドの第二引数 String[].class
この class は何なんだ!
調べまくって何となく分かったんだけど、要はこの class は実践編209ページの
Class インスタンスの基本的な取得方法の一つ

Class<?> cinfo = クラス名.class

の class と同じものだということ。
String[].class は文字列型配列に関するClassクラスのインスタンスである

リフレクションと呼ばれる分野について学習してるわけなんだけど
特徴的なのはあるクラスを対象とするとき、
そのクラスを対象とするClass クラスのインスタンスを生成する点

この先はざっくりとした説明になる。

場合によるのだろうが、この分野において、
メソッドに渡す引数の(クラス)型を指定するときも
同様の配慮をしなければならないようだ
つまり、メソッドの仮引数が
int i となっていたら、実引数は
int.class のように表現する場合があるということ

getMethod のレファランスを見てみると

public Method getMethod(String name,
Class<?>... parameterTypes)

Class<?> はまさにClassクラスのインスタンスをここにもってこいという事
0247おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 16:18:48.94
clazz の宣言文を補足する
例えばこんな風になる

Class<?> clazz = MemoryEater.class;
Method m = clazz.getMethod("main", String[].class);

これは、下のように書いてもよいということになる

Class<?> clazz = MemoryEater.class;
Class<?> stClazz = String[].class;
Method m = clazz.getMethod("main", stClazz);

分析の対象となるクラス(MemoryEater)もClassクラスのインスタンスを生成し
分析の対象となるクラスで使われる引数のクラス型(String[])についても
Classクラスのインスタンスを生成して使いなさい!ということらしい
0248おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 16:33:22.21
クラス名.class


クラスリテラルとかなんとか
タイプリテラルとか
リテラル記法とか

なにやらかなり特殊な書き方のようだ

今日はこれで終わり
0249おれさま ◆6CTEZS59O00a
垢版 |
2018/11/02(金) 16:05:26.41
自作Classに含まれるメソッドリスト

main
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll

これまで間違えてコードを書いてたみたいで
main以外表示されてなかったんだけど、さっき間違いに気づいて修正
こんなにでてきた
Objectクラスから引き継いだものも表示されるのな
複数のwaitはオーバーロードか
0250Mr.名無しさん
垢版 |
2018/11/03(土) 09:49:29.26
コマンドライン引数によって受けとったclassファイルを
ProcessBuilderによって起動するテストをeclipse上でやろうとすると失敗することが多い
というかclassファイルのソースコードを修正しては起動するみたいなことをしていると起動しなくなったりする
eclipse上ではなくてちゃんとコマンドラインから起動すれば正常に動くので
eclipseの問題なのか
まぁこれ以上ここに時間を費やすのもどうかと思うから追究するのはやめるか
0251おれさま ◆6CTEZS59O00a
垢版 |
2018/11/03(土) 16:42:46.49
今日はずっと前にやってたところの復習してた
せっかく覚えたのに忘れるのもったいないからたまにやらないとね
0252おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 08:00:49.41
9章269ページあたりを読んでるんだけど
System.out.println() とは結局何なのだろうかと。

System はクラス名で
out はそのフィールドで、型は PrintStream

つまり System クラスでは
PrintStream out;
みたいな宣言があるわけだ
(実際には public final static PrintStream out = null;)

んで、PrintStream クラスのメソッドの一つに
println() がある

out はクラス型をフィールドに用いたもの
すっきり入門340ページの Hero クラスのフィールドとして宣言されている
Sword sword;
と同じようなものか

341ページの下に
hsword.name
というのがあるが、もし Sword クラスの name フィールドが private で
getter が置かれているとしたら
@ h.sword.getName()
となっていたはず

これと
A System.out.println()
は結構似てると考えていいのか

違いは、@では Hero クラスの中で宣言されている sword は static ではないため
アクセスするには Hero クラスのインスタンス h を生成したが
Aでは、System クラスの中で宣言されている out が static 宣言されているため
インスタンス生成が不要だった点
0253おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 08:04:52.55
こういった構造を、フェイクを使いながら書くと、こんな感じになるのか
これでいいのかな
警告はでてるけど実行可

public class Main {
public static void main(String[] args) {
Systemm.outt.printlnn("aaa");
}
}
class Systemm {
static PrintStreamm outt;
}

class PrintStreamm {
public static void printlnn(String st) {
System.out.println(st);
}
}
0254おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 08:14:14.18
>>253の PrintStreamm#Printlnn から static を抜いたら警告が消えた
理由はあとで考えることにする

public class Main {
 public static void main(String[] args) {
  Systemm.outt.printlnn("aaa");
 }
}
class Systemm {
 public static PrintStreamm outt;
}

class PrintStreamm {
 public void printlnn(String st) {
  System.out.println(st);
 }
}
0255おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 09:22:15.30
例えばこのスレを 「2ch.txt」 に全コピペして保存

(例外は投げるとする)
FileReader fr = new FileReader("2ch.txt");
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
while (line != null) {
 System.out.println(line);
 br.readLine();
}

これだと文字化けしてしまう
そこで文字コードを指定したい

実践編260ページの記述によると、
FileReaderのコンストラクタで文字コード指定ができるかのように思われるが
実際はできない。いや出来るのかもしれないが調べた限りでは分からなかった ぞ

文字コードの指定には
FileInputStream
InputStreamReader
を使う
(この辺はHTML取得の時に使ったコードに似てる
URL、InputStream、InputStreamReader を使った)

FileInputStream fis = new FileInputStream("2ch.txt");
InputStreamReader isr = new InputStreamReader(fis, "SJIS");
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
while (line != null) {
 System.out.println(line);
 br.readLine();
}

これで文字化け回避できた
SJIS はググってでてきたものを適当にいれたらいけたってだけ
0256おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 09:34:16.09
TeraPad というテキストエディタを昔から使っているのだが、
下の方に文字コードが表示される
試しにこのスレやgoogleの検索結果のページやらをコピペしてみたり
パソコン内にあるいろんなファイルをTeraPadで開いてみたりしたが
全て SJIS と表示されていた

というか SJIS と指定して開いているからそう表示されるのかもしれないが
少なくとも、TeraPad でみたときに文字化けしていない状態で、SJIS と表示されているなら
SJIS がこの場合の正しい文字コードなんだなと

ちなみにeclipse上で、デフォルト文字コードを取得するこれ
System.out.println(System.getProperty("file.encoding"));
を確認してみると UTF-8 と表示される

この違いが文字化けの原因だ
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況