java

Java JNI の GetStringUTFChars は古い Unicode 仕様のシーケンスを返す

Unicode サロゲートペア範囲の "𡈽" という文字は、コードポイントが U+0002123D、UTF-8 のシーケンスだと [F0, A1, 88, BD] になる。JNI で "𡈽" のみで構成される String を以下のように UTF-8 に変換すると: const char *utf8 = env->GetStringUTFChars(…

Java でネイティブメソッドをオーバーライドして、インナークラスを引数で渡す場合の注意点

Java で以下のように native メソッドを定義する。 public class JniTest { static { System.loadLibrary("JniTest"); } class Inner { } native void hello(Inner inner); public static void main(String[] args) { JniTest test = new JniTest(); test.he…

Integer.parseInt(String, int) の使用上の注意

Integer.parseInt(String, int) には使用上注意しなければならない挙動があり、結果が負の値になる 16 進数文字列をパースすると NumberFormatException が発生する。わかりやすいのは以下の例。 Integer.parseInt("80", 16); // 128 Integer.parseInt("FFFF…

実行中の JVM のビットモード判定

実行中の JVM が 32bit なのか 64bit なのかを判定したい。以下のエントリのメソッドがシンプルに実装されていて良い感じ。 [java]動作中のJavaVMが32Bitか64Bitかを判別 - maachangの日記 上記エントリにも書かれているが、プロパティの名前と意味がわかり…

SWT の StyledText について調べたまとめ

SWT の StyledText は、簡単に言えば指定した範囲に任意の色を付けられるテキスト編集コントロール。Eclipse のエディタも、上位にドキュメントフレームワークがかぶさってはいるものの、基本的にこのコントロールが使用されている。この StyledText は、Can…

Thread の割り込みフラグは InterruptedException の throw によりクリアされる

例えば自身で作っているコード内で、呼び出し元の処理をブロックしたいようなケースはよくある。 String send(final String msg) throws IOException { Thread thread = new Thread() { private response; public void run() { os.print(msg); // 送信に不定…

wait() したい場合は、専用のオブジェクトで wait() しなければならない

今日遭遇した問題。以下のコードは、起動引数に何かを与えるとスレッドを起動して無限に待ち、何も与えないとスレッドを起動せずに無限に待つ。 public class Wait extends Thread { public static void main(String[] args) throws Exception { Wait w = ne…

String の + 演算 vs StringBuilder#append(String)

String は immutable なオブジェクトなので、例えば "1" + "2" というコードを書くと "1" の領域の最後に "2" がくっつくわけではなく "12" という新しいインスタンスが割り当てられる。だが "1" + "2" + "3" と書くと、"12" という String がまずできて、そ…

Integer.parseInt(String, int) にご注意

0xFFFFFFFF は 32 bit int で、型が符号付きなら -1 です。Java は符号なし int はないので、常に -1 なのですが、ちょっとした罠があります。以下は文字列 "FFFFFFFF" を int に直そうとするコードです。これを実行するとどうなるでしょう。 public class P…

WeakReference と ReferenceQueue

今日は新しい技を会得したぞ!Java のオブジェクトが GC で回収されたことを検知したい場合、いくつかの方法があります。対象のオブジェクトに finalize() を実装しておく、というのは最も簡単な方法ですが、副作用があるし、何より自分で実装したクラスじゃ…

Java の総称型は便利だけどちょっと残念

Java の総称型はかなり便利で、いやそれまでが不便だったんだけど、それに気がつかなかったということかも知れない。たとえばこういう宣言を見ると、ちょっと苦痛に感じる。 List list = new ArrayList(); このリストには何が入ってんだよ? 参照するときキ…

JDK のソースコードのコピーライトがヒドイ

Sun Microsystems のコピーライト条項に問題があったのか、以下のようにバッサリ削られている。 全部見たわけではないけど、多分全部こうだ。もう少しマシな消し方があったのではないか。

Javadoc の package.html をパースできない不具合

Javadoc は package.html という HTML をパッケージに配置しておけば、パッケージサマリーページとして取り込んでくれる。今まで数千の package.html を生成し、数十万行にわたるドキュメントを書いてきた私ですら、本日初めて遭遇する Javadoc のバグが見つ…

ブロックする InputStream を BufferedInputStream でラップしてはいけない

以下のコードを実行すると: import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; public class InputStreamTest { static class MyInputStream extends InputStream { int pos; byte[] data = "HelloWorld".getB…

フィボナッチで各種言語をベンチマーク

AWK、Ada、Bash、Boo、C、C#、C++、Clojure、D、Erlang、Forth、Fortran、Go、Groovy、Haskell、Io、Java、JavaScript、Lisp、Lua、OCaml、Objective-C、PHP、Pascal、Perl、Pike、Prolog、Python、R、Ruby、Scala、Scheme、Smalltalk、Tcl でフィボナッチ数…

Runtime#freeMemory() は正しい値を返さない

Runtime#freeMemory() に関して勘違いしていたのかも。 public class Memory { public static void main(String[] args) throws Exception { Runtime runtime = Runtime.getRuntime(); java.util.List<Object> list = new java.util.LinkedList<Object>(); for (int i = 0; i </object></object>…

main メソッドがなくてもコードが実行できる裏技が Java 7 で封じられた

class Test { static { System.out.println("Hello"); } } こんな main メソッドのないクラスをコンパイルして以下の要領で実行すると: java Test Java 1.6 までなら: Hello Exception in thread "main" java.lang.NoSuchMethodError: main という具合に s…

あまり知られていないと思われる Java のインスタンスイニシャライザの紹介

スタティックイニシャライザというのは Java をやってる人なら何度も使ったことがあると思う。Java を 10 年以上やっていて「インスタンスイニシャライザ」というものがあることを先日知った。 public class Test { int i; { // このブロックがインスタンス…

ThreadLocal というクラスを発見した

以下のような感じで使用する。 public class ThreadLocalTest { // これがスレッドローカル変数の原資 private static int num = 0; // 実体はひとつしかないが、スレッド毎に異なる値を返す変数 private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(</integer></integer>…

static final の命名規約

Java をやってる人なら、定数フィールドの名前はすべて大文字で命名する、というのは常識的なことだと思う。Java 言語仕様には以下のように記載されている。ただ、ここでは final にしか触れていない。Java Code Conventions には以下のように記載があり:fi…

Checkstyle の阻害

Java のソースコード静的解析ツール「Checkstyle」。導入しているチームは結構多いと思う。僕が思う Checkstyle を使用する阻害のひとつが、以下の警告。「最初の一文はピリオドで終わらなければなりません。」そのせいで、日本語のドキュメントにもかかわら…

Java の可変長引数を利用した HelloWorld

違和感がある Java 屋さんはお年寄りですよ(私のことです)。 public class Main { public static void main(String... args) { System.out.println("hello, world"); } }

Oracle Java のバグっぽいのを見つけた

何の変哲もないように見える以下の Java コード。これは実行するとエラーが発生します。どんなエラーが発生するかわかるかな? import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Test { public static void …

Java の総称型と Eclipse の警告と設計

以下のようなフィールドがあったとします。 private final List<String>[] list = new List[] { new ArrayList<String>(), }; このコードを Eclipse の標準設定で書くと、以下のような警告が出ます。 Type safety: The expression of type List needs unchecked conversion t</string></string>…

Java のインナークラスにおける裏舞台の全貌

今日 Java のインナークラスとリフレクション関連でいくつか発見したことがあったので、ここに残しておきます。以下のようなコードがあります。 import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class Foo { private class …

Thread.State.WAITING の Javadoc 誤訳

Java の Thread の振る舞いで少しハマったので、忘れないうちにメモ。Thread#getState() で取得可能なスレッドの状態いくつかあって、そのうち Object#wait() で無限に待っている状態であるかどうかを取得したい。Javadoc の日本語版を見ると、スレッドの状…

FindBugs の文字化け解消方法

FindBugs というツールを導入してみました。これは、Java のコードをチェックして、怪しい箇所を週出してくれるツールなのですが、Linux などの UTF-8 環境だと、日本語化されたメッセージが文字化けするという問題があります。いろいろ調べた結果、FindBugs…

Eclipse + CDT で突然死ぬ場合の対処

以下の組み合わせで問題が発生した。 64bit Ubuntu + Sun-Java6-JDK + Eclipse Helios 64bit + CDT これが Sun-Java5-JDK だと問題が発生しない。 解決方法としては eclipse.ini の -vmargs の下に -XX:+UseCompressedOops をつけること。これは Java6 の途…

昔 SWT で作っていたエディタのスクリーンショットが出てきた

2007 年頃 SWT でクロスプラットフォームなエディタが作れないかと検証して、途中でやめたきっかけの画像。テスト用に hello と world がそれぞれキーワードになっていて、異なる強調表示をするというテストをしていた。ずいぶん前で、ソースもどこにあるか…

C と Java における代入式の左辺と右辺の評価順序

#include <stdio.h> int main(int argc, char *argv[]) { int a[2] = { -1, -1 }; int i = 0; a[i] = ++i; printf("a[0]=%d\na[1]=%d\n", a[0], a[1]); return 0; } こんな短いコードを gcc と cl でそれぞれコンパイルして実行すると、gcc だと a[0]=1 a[1]=-1cl だ</stdio.h>…