たかずんドットコム

文系Webプログラマから生み出される杜撰なTipsと日常の記録

「Javaプログラマであるかを見分ける10の質問」をJava初心者に説明する解を考える

お疲れ様です。たかずんです。

かなりの間、ブログ更新停滞しておりました。 最近は、Webサービスの設計業務と新人教育ばかりしており、あまりプログラミングが出来ていない日々が続いております。

Javaプログラマであるかを見分ける10の質問にチャレンジ

新人教育の肥やしになるかと思い、以下のブログのエントリを閲覧しておりました。 d.hatena.ne.jp そこで、記事内の問題に解答しつつ、Java初心者の新人にどうやって解説するかを自分なりに展開してみたいと思います。
私の現時点での理解度によるものなので、至らない点が多々あるかと思いますが、生暖かい目で見守ってください。

==演算子とequalsメソッドの違いは何か?

⇒同参照か同値かの違いです。
(解説)
Javaの場合、基本データ型参照型があり、String型は参照型です。
==演算子は比較対象の参照オブジェクトが同一かを比較します。 String型の文字列オブジェクトが同値であっても,、==ではインスタンスが別のためfalseと判断します。 equalsメソッドであれば値による比較がおこなれるため、無事trueを返してくれます。
まずは、String型とは何かを把握しなければならない難しい問題の一つですね。
【Java】 そもそもStringって何? | 一番かんたんなJava入門

文字列の+演算子による連結とStringBuilderを使った連結の違いを説明せよ。文字列の連結は原則として+演算子を使ってはならない理由を説明せよ。

⇒+演算子の場合、インスタンスをいくつも生成してしまう。StringBuilderの場合は、単一インスタンスによる文字列連結が可能。
(解説)
+演算子を利用した際、コンパイラによって文字列連結が最適化されるため、StringBuilderインスタンスを生成しappendメソッドを実行することとなります。 不要なインスタンスを生成してしまうため原則として+演算子による連結は良くないとされています。(たぶん
ただ、現状のマシンパワーであれば些細なパフォーマンスの差ですので、単一文章の結合には+演算子を使うことが好ましいとされます。また、ループ処理等により 複数の文章を結合する場合は、StringBuilderを利用することが好ましいとされます。
初心者にだらだら説明するよりも、社内のコーディング規約に則った文字列結合の仕方を教え、「何故、そういう取り決めなのかな?」と思わせると良いのかな?

Listのようにジェネリクス型を使う主たる目的は何か?

⇒戻り値の型を保証するため
(解説)
Listインターフェースに型を明示しない場合、戻り値の型はObject型に補完されます。 例えば、数値を格納するリストとして使いたい場合であれば、取り出して利用する際に数値型にキャストする必要が出てきます。しかし、リストにはオブジェクトであれば何でも値をadd出来るため、 もし文字列が誤って混在した場合、数値型にキャストする部分でエラーとなってしまいます。そういったケースを回避するため、あらかじめ型を定義し、戻り型を保証する必要があります。

オブジェクトがガベージコレクションGC)される主たる条件は何か?

⇒どこからも参照されなくなった時
(解説)
GCVMが勝手に判断して行うものなので、プログラマが介入することは基本的にありません。
オブジェクトのインスタンスはヒープエリアに格納され、ヒープエリアの使用率が一定に昇った時点でどこからも参照されていないインスタンスがあればGCの対象となり、破棄されます。
「newされたインスタンスはエデンに産み落とされる」とか言っておけば出来る子は勝手に調べ始めます。

チェック例外と非チェック例外の違いを型と例外処理の観点で説明せよ。

⇒チェック例外はcatch構文で捕捉、もしくは親元にthrowされる。非チェック例外は意図しないシステムエラー的なもの(笑)
(解説)
ちょっと問題の意図が分かり辛いので適当に答えました。
意図した例外を捕捉したい場合はメンドクサイけどtry~catch構文で捕捉しましょう。

フィールドのアクセス修飾子をprivateにしgetter/setterメソッドを提供する事でフィールドを参照する設計方針を取る主な理由を説明せよ

⇒JavaBeansの規格のため (解説)
答えといて何ですがJavaBeansについては勝手に調べてください。
カプセル化の観点では、フィールドへの直接的なアクセスを提供すると後変更への対応が困難となるので、値の受け渡し用のメソッド(アクセサメソッド)を作成して、 実フィールドは隠ぺいし、保守の効率をあげましょうということになっています。 int型のフィールドにたくさんの場所で値を直接入れてたんだけど、「実はこれBigDecimal型だったんだ~」となった時に全部の場所で値のキャストが必要になってしまう。 しかし、アクセサメソッドを用意しておけばそれを更新するだけで済むんだぜ!?すごいだろ~というお話。

NullPointerExceptionが発生するのは主にどういう状況か?

⇒nullを参照しているオブジェクトやメソッドを呼び出した場合
(解説)
ぬるぽ→ガッってネタは今は通じないようです。
C言語で勉強したポインタのことです。ポインタの実態がなかったり、中身がnullだったりするとこのエラーが発生します。

オーバーロードとオーバーライドの違いは何か?

オーバーロードは引数の値、順序を変えた同名メソッドを定義し振る舞いの違いを実現する。オーバーライドは継承したクラスのメソッドを再定義する。
(解説)
複数の型で引数を取りうるメソッドの場合、オーバーロードを利用することでスッキリとした実装を実現できます。ただし、誤用は避けるようにしてくださいね。
オーバーロードの誤用 - 日々常々
オーバーライドを使うことで、継承した一部機能の変更が出来るようになります。ただし、取りうる引数や戻り値は一緒である必要があり、あくまで内部処理に手を加えたい場合に 利用します。

コンストラクタとは何か?

インスタンス初期化時に実行されるメソッドのようなもの
(解説)
必ずそのオブジェクトを戻り値として返すメソッドのようなものです。オブジェクトの初期化処理を書くことが目的であり、引数を取ることも可能です。前述のオーバーロードを利用して 引数によって初期化処理を変えたりすることも可能。

インターフェイスを利用する目的を1つ説明せよ

⇒仕様から実装を切り離すため (解説)
「このクラスのこのメソッドを利用すると~~という結果を得られます」 といった仕様を策定するのがインターフェースの主な役割です。java初心者に言葉だけで説明するのは非常に難しい問題です。
わかりやすい例えは以下を参考にしてください。(私では無理です
interfaceについて本気出して考えてみた - 都元ダイスケ IT-PRESS
やりたいこと(仕様)があって、様々な実現方法(実装)がある場合にインターフェースを利用するというイメージを持ってもらえるといいと感じました。 また別記事で自分なりの良い例えが書ければなぁって思ったりしています。

まとめ

技術的な言葉を用いれば簡潔に説明出来るのですが、Java初心者に対してわかりやすい説明をするとなると難しいですね。。。
まぁ、詰まる所プログラミングの学習は自主学習に依るところが大きいので、部下に教える際は、口うるさいぐらい検索用のワードを強調することを私は意識しています。 それで指導として適切なのかはまだ私はわかっておりません。。。むむぅ。

では、この辺で失礼致します。

EFFECTIVE JAVA 第2版 (The Java Series)

EFFECTIVE JAVA 第2版 (The Java Series)

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

Green Daoを導入してSQLiteの利用を簡便化 ~ジェネレータ導入~

前回やることリストに上げていたGreenDaoの導入をしました。
AndroidSQLiteのORMライブラリは結構あるんですけど、その中でもとにかく早いといわれているGreenDaoを選択しました。リフレクションを多用するものや、そもそもSQLを利用しないコンセプトのものが出始めている中で、独自のクエリーをかなりの自由度で実装できて、尚且つ軽いというのは非常に良いライブラリだと感じます。

何はともあれ、gradleで導入

dependencies {
    // ...etc libs
    compile 'de.greenrobot:greendao:1.3.7'
}

これでGreenDaoを利用する環境は整いました。
お次は、GreenDaoで利用するエンティティとそのマネージャーを作成するために、GreenDaoGeneratorなるJavaプロジェクトを作成します。

とりあえず以下のブログ記事が参考になりますので並行して参照してください。

GreenDaoGeneratorプロジェクトを作ってみる

上記記事に沿って導入してみました。eclipseに作ったプロジェクト階層はこんな感じ。
f:id:takazune:20150218114029j:plain

libsフォルダに記事内で紹介されているgreendao、greendao-generator、freemarker.jarの3つを入れて、それぞれを外部jarとしてビルドパスに組み入れます。
GreenDaoGenerator.javaの中身はこんな感じ。

public class GreenDaoGenerator {

    public static void main(String[] args)  throws Exception {
        Schema schema = new Schema(3, "hoge.hoge.db");
        addListItem(schema);
        new DaoGenerator().generateAll(schema, "./");

    }

    private static void addListItem(Schema schema) {
        Entity listItem = schema.addEntity("ListItem");
        listItem.addIdProperty().autoincrement();
        listItem.addStringProperty("listVal").notNull();
        listItem.addLongProperty("position").notNull();
        listItem.addDateProperty("updateDate").notNull();
        listItem.addDateProperty("createDate").notNull();

        Entity taskItem = schema.addEntity("TaskItem");
        taskItem.addIdProperty().autoincrement();
        Property listItemId = taskItem.addLongProperty("listItemId").notNull().getProperty();
        taskItem.addStringProperty("taskVal").notNull();
        taskItem.addLongProperty("position").notNull();
        taskItem.addDateProperty("updateDate").notNull();
        taskItem.addDateProperty("createDate").notNull();

        taskItem.addToOne(listItem, listItemId);
        ToMany listItemToTaskItem = listItem.addToMany(taskItem, listItemId);
        listItemToTaskItem.setName("tasks");
    }
}

あってるかどうかわかりませんが、これでlistItem,taskItemという2つのテーブルが作られます。

new DaoGenerator().generateAll(schema, "./");

で階層を自身のプロジェクト直下を指定しており、このjavaを実行するとプロジェクト直下に(hoge.hoge.db)ディレクトリが作られて、その中にDAOが生成されます。あとは、出来上がったそれをandroidのプロジェクトにぶち込めばOK。ジェネレーターはaddメソッドを切り替えれば他のプロジェクト用のDAOもすぐ作れるので、一度作っておくと楽です。

アンドロイドのプロジェクトで利用してみる

次回の記事で生成したDAOを使ってDBにアクセス出来るようにします。

リストビューの表示の仕方にアニメーションを付与する

前回記事(ListViewAnimationsライブラリをGradle経由で導入してみる - ライツサカナアクション)で導入したListViewAnimationsを利用して、リストビューのアイテムの表示時にアニメーションを付与します。

とりあえず何かしらのアダプターを用意して、

hogeListView= (ListView) view.findViewById(R.id.hogeList);
hogeAdapter= new HogeAdapter(Context context);

SwingBottomInAnimationAdapter animationAdapter = new SwingBottomInAnimationAdapter(hogeAdapter);
animationAdapter.setAbsListView(hogeListView);
hogeListView.setAdapter(animationAdapter);

こんな感じにする。hoge系をご自分のものと置き換えてちょ。
SwingBottomInAnimationAdapter以外にも、、、

  • AlphaAnimationAdapter
  • ScaleInAnimationAdapter
  • SwingBottomInAnimationAdapter
  • SwingLeftInAnimationAdapter
  • SwingRightInAnimationAdapter

ListViewAnimations by nhaarman

これでリストビューが表示される時に指定のアニメーションをするようになります。
ただ、表示するだけでは味気ないなと感じたら使ってみるといいかも。

ListViewAnimationsライブラリをGradle経由で導入してみる

ListViewに表示アニメーション、スワイプ削除、ドラッグ&ドロップとかをまとめて実装できるライブラリListViewAnimationsを導入。  

nhaarman/ListViewAnimations · GitHub

導入方法は、ソースを直接ぶっこんだり、Mavenで管理することも出来るが、今回はGradleで導入。おそらくこれが一番簡単。
build.gradle(Module: app)に下記を追加

repositories {
    mavenCentral()
}

dependencies {
    compile 'com.nhaarman.listviewanimations:lib-core:3.1.0@aar'
    compile 'com.nhaarman.listviewanimations:lib-manipulation:3.1.0@aar'
    compile 'com.nhaarman.listviewanimations:lib-core-slh:3.1.0@aar'
}

追記してSyncすることでライブラリが自動でインポートされます。ただ、libsフォルダにライブラリソースをインポートしているだけなので、dependenciesに以下の記載が無ければ忘れずつけること。

compile fileTree(dir: 'libs', include: ['*.jar'])

これでlibsのjarファイルにパスが通ります。(私はdependenciesを二つ書いていてハマリました)
あとアニメーション表示をNineOldAndroidsライブラリでGingerBread以前にも適用させているので、導入していない方は以下も追加。

compile 'com.nineoldandroids:library:2.4.0'

詳しくは、ネタ帳 A.B.C: NineOldAndroidsを使ってみた

AndroidStudioのライブラリの導入は非常に簡易で助かります。あれもこれもGradleさんのおかげ。
とりあえず今回は導入だけ。ネット上にリソースが上がっているライブラリであれば同様に使えるインポート方法なので参考になれば幸いです。

ゆらゆら帝国みたいな音楽が私には不足しています

嫌なことがあると坐禅しながら目を閉じて音楽を大音量で聞きます。
音楽好きなんですけど、楽器とか出来ないし、よくわからない。どう評価したらいいかわからないので、基本的には自分の直感とかフィーリングで聞く曲は決めてます。
そんな私でも自信を持って好きと言えるアーティストは、、、ゆらゆら帝国。でしょうか。

高校時代に友達に勧められたのがきっかけ(どんな友達だ)なんですけど、どハマりしちゃって。
タコ物語とか貫通前とかボーンズとか好きです。19か20のイントロは痺れます。空洞ですのアルバムは何回通してローテしたかわからない。

空洞です

空洞です

で、「ゆらゆら帝国が好き」って言うとバンドやってる友達とかは凄いよろこんでくれる。音楽やってない自分からすると、何でそんなによろこんでくれるのかわからない。どう評価されてるのかもよくわかってない。ただ、自分のフィーリングは間違ってなかったのかなって嬉しくは思う。
話の流れで好きなアルバムを聞かれて、「スイートスポット」って答えるとさらに盛り上がる。笑

Sweet Spot

Sweet Spot

もうね、最高ですよ。ソフトに死んでいるとか凄い。意味わかんない! あと解散後、坂本さんのソロ曲もいいですよねー。

まともがわからない

まともがわからない

で、ゆらゆら帝国みたいなエッセンスを含んでるアーティストとかいないのかなーって思うんです。でも、音楽のうんちくが足らなくてうまく探せない。ヤキモキする。うん、おすすめ教えて下さい。P-MODELとかも好きです。もっとメジャーだとアジカンとか。海外だとMuseとかOK GOとかダフトパンクとかBeasty BoysとかKooksとかBlack KeysとかFall Out Boyとか。。。

おすすめの探し方とかあれば。いじょ。

戻るボタンで前のフラグメントに戻る処理を実装する

前回記事で、

ActivityとFragmentを利用して画面遷移を実装させる - たかずねブログ

FragmentManagerを利用して、フラグメントの切り替えを実装しました。
今回は戻るボタンを押した際に、前のフラグメントに戻る機能を実装します。

とりあえず、こんな感じの切り替えメソッドを実装。

private void replaceFragment(Fragment f) {
        FragmentTransaction transaction = 
        getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.container, f);
        transaction.addToBackStack(null);
        transaction.commit();
    }

replace(addでも可)で切り替えた後、

transaction.addToBackStack(null);

するのがミソ。 nullが入っている部分は、String型で識別キーを指定できます。
次に戻るボタンが押された際のメソッドを定義します。

@Override
    public void onBackPressed() {
        int backStackCnt = 
        getSupportFragmentManager().getBackStackEntryCount();
        if (backStackCnt != 0) {
            getSupportFragmentManager().popBackStack();
        }
    }

onBackPressedメソッドをオーバーライドして、処理を書き換える。 マネージャーに存在するバックスタック数が1以上あるならば、popBackStackで直前のスタックに遷移します。

もし、戻り先を指定したいときは、、、

transaction.addToBackStack("hoge");  

という感じで識別キーを指定してあげて、

getSupportFragmentManager().popBackStack("hoge");

ってな感じにすることで指定位置に戻ることが可能です。
私の記事でわからないことは、以下からどうぞ

5月 | 2011 | それは叩いても直らない

ActivityとFragmentを利用して画面遷移を実装させる

ActivityとFragmentを1:nで利用するのが最近の主流なのでしょうか。

ActivityにFrameLayoutを用意して、その中身にFragmentを表示するやり方を行うことで、一つのActivityでいくつもの画面(フラグメント要素)を実装することが出来ます。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hoge);

        if (savedInstanceState == null) {
            HogeFragment fragment = new HogeFragment();
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
            transaction.add(R.id.container, fragment).commit();
        }
    }

これでidがcontainerのFrameLayoutにHogeFramentを表示できます。フラグメントにもアクティビティと同様のライフサイクルがあり、commit()することでフラグメントが生成されます。 フラグメントのライフサイクルについては、

を参照してください。正直あんまりわけわかってないです。。。

んで、違うフラグメントを表示したいよーって時は、

public void changeFragment(Fragment fragment) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.add(R.id.container, fragment);
        transaction.commit();
    }

みたいなメソッドを作って呼び出せばOKです。
transaction.addの部分ですが、replaceでも大丈夫です。replaceの場合、今割り当てられている全てのフラグメントをremoveし、その後addの動作を実行するようです。
フラグメントをaddしまくって階層が深くなるとスタックオーバーフローしちゃうみたいなんで、基本的にはreplaceを使うみたいですね。

Android初心者におすすめする「Fragmentによるシンプルで効率的なUI実装」#Android #yahoo|CodeIQ MAGAZINE

Y.A.M の 雑記帳: Android FragmentTransaction のまとめ

参考になれば幸いです。