FC2ブログ
HOME   »  2012年02月
Archive | 2012年02月

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Java]byte型数値を符号なし数値として扱う

byte型は8ビットの整数だが、符号付きの為最上位ビットが符号(+/-)を表し、値の範囲は0~255ではなく-128~127となる。

このbyte型の値を符号なしの値(範囲が0~255)として扱いたい場合は、byte型よりもビット数が多いint型等に変換すればよい。
ただし単純に変換すると、符号拡張で負値は負値のままとなってしまうので注意が必要。

例えば、byte型の-1(16進数表示でFF)を単純にint型に変換(int型変数への代入による暗黙の変換)すると、変換後の値も同じく-1のままとなる。
public class Main {
    public static void main(String[] args) {
        byte byteValue = (byte) 0xFF;
        int intValue1 = byteValue;
        System.out.println(String.format("byte型 byteValue (16進数表示):%X", byteValue));
        System.out.println(String.format("byte型 byteValue (10進数表示):%d", byteValue));
        System.out.println(String.format("int型 intValue1 (16進数表示):%X", intValue1));
        System.out.println(String.format("int型 intValue1 (10進数表示):%d", intValue1));
    }
}
上記の実行結果は以下の通り。


byte型 byteValue (16進数表示):FF
byte型 byteValue (10進数表示):-1
int型 intValue1 (16進数表示):FFFFFFFF
int型 intValue1 (10進数表示):-1


int型変数intValue1への代入の際の符号拡張により、上位24ビットが全て符号ビットと同じ値1で埋められ、その結果負値のままとなっている。

この16進数表示でFFとなる値を正値255として扱いたい場合は、int型の値255(32ビットの16進数表示で000000FF)との論理積演算により上位24ビットを全て0にしてやればよい。
public class Main {
    public static void main(String[] args) {
        byte byteValue = (byte) 0xFF;
        int intValue1 = byteValue;
        int intValue2 = byteValue & 0xFF;
        System.out.println(String.format("byte型 byteValue (16進数表示):%X", byteValue));
        System.out.println(String.format("byte型 byteValue (10進数表示):%d", byteValue));
        System.out.println(String.format("int型 intValue1 (16進数表示):%X", intValue1));
        System.out.println(String.format("int型 intValue1 (10進数表示):%d", intValue1));
        System.out.println(String.format("int型 intValue2 (16進数表示):%08X", intValue2));
        System.out.println(String.format("int型 intValue2 (10進数表示):%d", intValue2));
    }
}
上記の実行結果は以下の通り。


byte型 byteValue (16進数表示):FF
byte型 byteValue (10進数表示):-1
int型 intValue1 (16進数表示):FFFFFFFF
int型 intValue1 (10進数表示):-1
int型 intValue2 (16進数表示):000000FF
int型 intValue2 (10進数表示):255


int型の値255との論理積演算を行った結果のintValue2は正値255となっている。


スポンサーサイト

[Java]InputStreamの読み出しデータを格納した配列型変数の状態

InputStreamクラス(を継承したクラス)のreadメソッドの引数として使用し、読み出したデータを格納した後の配列型変数の状態について。

まず、英大文字の"A"、"B"、"C"の3文字を記したテキストファイル(test.txt)を作成し、以下の様にFileInputStreamクラスを使用してこのファイルからデータを読み出す。
public class Main {
    public static void main(String[] args) {
        File file = new File("/*****/test.txt");
        FileInputStream fileInputStream;
        int readDataLength;
        byte[] buffer = new byte[]{0, 1, 2, 3, 4};
        try {
            fileInputStream = new FileInputStream(file);
            readDataLength = fileInputStream.read(buffer);
            fileInputStream.close();
            System.out.println("読み出したデータ数:" + readDataLength);
            System.out.println("配列型変数bufferの要素数:" + buffer.length);
            for (int i = 0; i < buffer.length; i++) {
                System.out.println("buffer[" + i + "]:" + buffer[i]);
            }
        } catch (Exception e) {
        }
    }
}
上記を実行すると、以下の様に読み出したデータ数readDataLength、読み出したデータを格納した配列型変数bufferの要素数buffer.length、配列型変数bufferの各要素の値がコンソールに表示される。


読み出したデータ数:3
配列型変数bufferの要素数:5
buffer[0]:65
buffer[1]:66
buffer[2]:67
buffer[3]:3
buffer[4]:4


上記の結果から、以下の事が分かる。

・読み出したデータは、配列型変数の先頭(インデックス0)から順に読み出したデータ数分だけ格納される。
・配列型変数の要素数は、読み出したデータを格納した後も変化しない(配列型なので当然か)。
・配列型変数の中で読み出したデータが格納されなかった箇所の要素は、読み出し前の値がそのまま保持される。


[Java]スーパークラス型変数へのサブクラスインスタンス代入時の挙動

スーパークラス型の変数にサブクラスのインスタンスを代入した時の挙動について。

以下の様なあるクラス(Superクラス)とそのクラスを継承したクラス(Subクラス)を作成する。

○Superクラス(スーパークラス)
public class Super {
    public Super() {
    }
    
    public void showMessage() {
    	System.out.println("スーパークラスのメソッドが実行されました。");
    }
}
○Subクラス(サブクラス)
public class Sub extends Super {
    public Sub() {
    }

    @Override
    public void showMessage() {
        System.out.println("サブクラスのメソッドが実行されました。");
    }

    public void showMessageOfSub() {
        System.out.println("サブクラス独自のメソッドが実行されました。");
    }
}
そして、以下の様にSuperクラス型変数instanceにSubクラスのインスタンスを代入し、showMessageメソッドを実行するとどうなるか。
public class Main {
    public static void main(String[] args) {
        Super instance = new Sub();
        instance.showMessage();
    }
}
上記を実行すると、コンソールには以下の様にメッセージが表示される。


サブクラスのメソッドが実行されました。


変数instanceはSuperクラス型だが、参照先はSubクラスのインスタンスであり、showMessageメソッドはSubクラスでオーバーライドされている為、Subクラス側のメソッドが実行されることになる。

では、Subクラスでのみ実装されているshowMessageOfSubメソッドはどうか。
public class Main {
    public static void main(String[] args) {
        Super instance = new Sub();
        instance.showMessageOfSub();
    }
}
上記を実行すると、コンパイルエラーとなってしまう。

上述の通り変数instanceはSuperクラス型であり、SuperクラスにはshowMessageOfSubメソッドが存在しない為、実行することができない。

以上の挙動は、メソッドの引数の場合も同様である。

以下の様にSubクラス型変数instanceをtestMethodメソッドの引数として渡してみる。
public class Main {
    public static void main(String[] args) {
        Sub instance = new Sub();
        testMethod(instance);
    }

    public static void testMethod(Super object) {
        object.showMessage();
        //object.showMessageOfSub();
    }
}
上記を実行すると、先の例と同様にコンソールには以下の様にメッセージが表示される。


サブクラスのメソッドが実行されました。


testMethodメソッドの仮引数objectはSuperクラス型、実引数instanceはSubクラス型である為、showMessageメソッドはSubクラス側のメソッドが実行され、showMessageOfSubメソッドは実行することができない(9行目のコメントアウトを解除するとコンパイルエラーとなってしまう)。


[Android]BluetoothのSPPで使用するUUID

BluetoothをSPP(Serial Port Profile)で使用する場合、BluetoothDeviceクラスのcreateRfcommSocketToServiceRecordメソッド等の引数として設定するUUIDは、以下の値を使用する必要がある。

00001101-0000-1000-8000-00805F9B34FB

Android SDK付属のサンプルアプリケーション「Bluetooth Chat」では、このUUIDが

FA87C0D0-AFAC-11DE-8A39-0800200C9A66

となっているので注意が必要。

尚、UUIDクラスのfromStringメソッドを使用して文字列からUUIDクラスのインスタンスを取得する場合は、引数の文字列をRFC 4122で規定されている以下のフォーマットで設定する必要がある。

"4バイト(8文字)-2バイト(4文字)-2バイト(4文字)-2バイト(4文字)-6バイト(12文字)"


プロフィール

まさお

Author:まさお
プログラミングは趣味レベルなので、お手柔らかに。

ブログランキング
ブログランキング参加中。是非クリックお願いします。


にほんブログ村 IT技術ブログ Androidアプリ開発へ

人気ブログランキングへ

ブログランキング



ブログ王

ブログランキング【ブログの惑星】

プログラム人気ブログランキング
最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。