[Java] StringBuilder に null を append すると

StringBuilder を使用していて、たまたまNULLを追加したら、
そのまま "null" という文字が追加されてしまいビックリした。


StringBuilder sb = new StringBuilder();

String nullString = null;

sb.append("A");
sb.append(nullString);
sb.append("B");
System.out.println(sb.toString());



上記プログラムの出力結果は、

AnullB


AとBの間に "null" の文字が。。。
でも、これは仕様のようですね。

Javadoc にも明記されていました。
The characters of the String argument are appended, in order, increasing the length of this sequence by the length of the argument. If str is null, then the four characters "null" are appended.


[Java] メソッドの引数は基本的には参照渡し

Javaでは、メソッドの引数で渡す値は基本的に参照先の情報(参照渡し)である。
※例外としてプリミティブ型の場合は値渡しのようです。

参照渡しということは、引数で渡された変数は、呼び出し先のメソッド内で値を変更すると呼び出し元の変数の情報が更新されると考えられます。

でも、単純に考えているとハマってしまう。
# C言語のようにポインタで明示的に扱えればいいのだが。。。

たとえば、String型を使用した以下のようなコードでは呼び出し元の値は変わっていない。


public static void main(String[] args) {
String str = "aaa";
System.out.println("サブメソッド呼び出し前 :" + str);
sub(str);
System.out.println("サブメソッド呼び出し後 :" + str);
}

public static void sub(String str) {
str = str + "bbb";
System.out.println("サブメソッド内で\"bbb\"を追加:" + str);
}


【実行結果】
サブメソッド呼び出し前 :aaa
サブメソッド内で"bbb"を追加:aaabbb
サブメソッド呼び出し後 :aaa


サブメソッド内で "bbb" を追加しているので、サブメソッド呼出し後は "aaabbb" になるかと考えがちだが、実際は "aaa" になっている。

これは、
str = str + "bbb"; (★)
で代入する際に、Stringインスタンスを新たに生成しているため、
参照先が変更された状態で代入される。

上記の(★)の式では2つの str の参照先は異なる。
 左の str の参照先:サブメソッド内で新しく生成されたStringインスタンス
 右の str の参照先:メインメソッドから渡されたStringインスタンス

ちなみに、Integer、Double、Longなども実行結果は String と同じようになりました。

public static void main(String[] args) {
Integer integer = 10;
System.out.println("サブメソッド呼び出し前 :" + integer);
sub(integer);
System.out.println("サブメソッド呼び出し後 :" + integer);
}

public static void sub(Integer integer) {
integer = integer + 20;
System.out.println("サブメソッド内で\"20\"を追加:" + integer);
}


【実行結果】
サブメソッド呼び出し前 :10
サブメソッド内で"20"を追加:30
サブメソッド呼び出し後 :10



サブメソッド呼び出し後に値が変わっているような場合のサンプルは以下になる。
例)StringBuilderを使用した場合

public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("aaa");
System.out.println("サブメソッド呼び出し前 :" + sb.toString());
sub(sb);
System.out.println("サブメソッド呼び出し後 :" + sb.toString());
}

public static void sub(StringBuilder sb) {
sb.append("bbb");
System.out.println("サブメソッド内で\"bbb\"を追加:" + sb.toString());
}


サブメソッド呼出し後に呼び出し元の変数も "aaabbb" というように "bbb" が追加されていることがわかります。




[Android] 画面遷移直後にIMEが自動的に起動するのを防ぐ

遷移先の画面の初期フォーカス位置がEditTextである場合、自動的にIMEが起動してしまう。

・初期フォーカスはEditTextのままにしたい
・最初にIMEが自動起動しないようにしたい

この2つを満たしたいので、ちょっと調べてみた。


IMEの制御なので、InputMethodManagarでどうにかするのかと思っていましたが、違った方法でできるようです。


import android.view.WindowManager.LayoutParams;

・・・

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

this.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

setContentView(R.layout.main);

・・・


こんな感じで実装したら、期待通りの動作になりました。


[Android] Caused by: java.lang.ClassCastException: android.app.Application

E/AndroidRuntime(12613): Caused by: java.lang.ClassCastException: android.app.Application

Applicationクラスを継承したクラスオブジェクトを getApplication() で取得しようとしたら、上記のようなエラーが出てきた。

特に、Eclipse上ではコンパイルエラーなどは出ていないのだが、実行すると強制終了。。。


原因は単純でした・・・

AndroidManifest.xml にApplicationクラスを継承したクラスを定義してませんでした。。。
applicationタグの android:name属性にクラスを定義してあげます。

<application
  android:name="★★★クラス名★★★"
 ・・・

Manifestに追記したら、無事エラーがでなくなりました。
久しぶりですっかり、忘れてた。。。


プロフィール

hiiro

Author:hiiro

最新記事
カテゴリ
月別アーカイブ
最新コメント
最新トラックバック
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
Counter