読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

Java変態?コード最速マスター

Java

Java変態文法最速マスター - プログラマーの脳みそが面白かった && 参考になったので便乗してリスペクト。変態世間であまり見かけない(かも知れない)Javaコードを、過去のエントリからまとめてみました。

nullでなければループ

「配列がnullでなければループ」というシーンはまれにありますが、nullチェックのためにインデントが深くなるのが我慢ならん、というときにこういう記述はどうでしょう。

String[] strs = // 略

// 配列がnullでなければ各要素に対して処理を実行
if ( strs != null ) for ( String str : strs ) {
    // 処理
}

if文の「{}」を省略してforを繋げているだけですが、インデントをさりげなく削れます
似たような例で、「例外を無視して次へ」とかも。

// 例外が発生しても無視して次へ
for ( String str : strs )  try {
    // 処理
} catch ( Exception e ) {}

ちなみに、これはできそうでできません。(synchronized はステートメントを受け付けない。)

synchronized( lock ) if ( obj == null ) {
  // 処理
}

see : http://d.hatena.ne.jp/unageanu/20090819/1250678246
see : http://d.hatena.ne.jp/unageanu/20090422/1240402184

インターフェイスに実装を書く

無名クラスを使うことでインターフェイスにも実装を書けますインターフェイスは切っておきたいけど、XXXImpl.javaを別に用意するのはメンドイ、というときに使えます。

import java.io.File;

/**
 * 一時ファイルディレクトリ解決サービス
 */
public interface TemporaryDirectoryService {

    /**
     * 一時ファイルディレクトリを取得する。
     * @return 一時ファイルディレクトリ
     */
    File getTemporaryDirectory();

    /**
     * {@link TemporaryDirectoryService}のデフォルト実装。
     */
    TemporaryDirectoryService DEFAULT = new TemporaryDirectoryService () {
        public File getTemporaryDirectory() {
            String path = System.getProperty( "tmpfolder", "/tmp" );
            return new File(path);
        }
    };
}

see: http://d.hatena.ne.jp/unageanu/20070821

インターフェイスでstaticブロック

↑と似たようなネタですが、無名クラス+インスタンスイニシャライザで、インターフェイスにstaticブロックを作ったりも。

public interface Foo {
    .../** 必要なシステムプロパティを設定。*/
    Object INIT = new Object(){{
        System.setProperty( "foo", "var" );
    }};
}

see : http://d.hatena.ne.jp/unageanu/20090701/1246455537

Javaでcallee

JDK5からですが、無名クラスからそれを定義したメソッドの参照を取得できるようになったので、Javaでもcalleeが可能になっています。

/**
 * メソッド自身を取得する。
 * @param o メソッド内で作成した無名クラス
 * @return メソッド自身
 */
static Method callee( Object o ) {
    return o.getClass().getEnclosingMethod();
}

/**
 * currentが10になるまで再帰する関数。
 * @param current
 */
static void count( int current ) {
    System.out.println( current );
    if ( current >= 10 ) {
        return ;
    } else {
        try {
            // メソッド自身を取得する。
            callee( new Object(){} ).invoke( null, current+1 );
        } catch ( Exception e ) {
            e.printStackTrace();
            return;
        }
    }
}

「new Object(){}」でさりげなく無名クラスを生成するのがポイントかな。「ログ出力時に操作名(メソッド名)を出力しろ」とかいう場合のメソッド名取得に使えないかと画策中。

see: http://d.hatena.ne.jp/unageanu/20071031/1193831894

共通の上位クラスを探す。

「推論の元になる引数が複数ある場合、共通の親クラスが使われる」ことを利用して、共通の上位クラスを探す関数を作れます。

// 引数の共通の親クラスを返す。
static <X> Class<?> test( X... args ) {
    return args.getClass().getComponentType();
}
....
public static void main( String[] args ) {
    System.out.println( test( "a" ) ); // String
    System.out.println( test( "", new Object() ) ); // Object
    System.out.println( test( 1, 1D ) ); // Number
    System.out.println( test( new IOException(), new RuntimeException() ) ); // Exception
}

実行結果です。

class java.lang.String
class java.lang.Object
class java.lang.Number
class java.lang.Exception

see: http://d.hatena.ne.jp/unageanu/20081016/1224158075

複数インターフェイスを実装したオブジェクトのみ受け付けるAPI

これは有名かもですが、型パラメータで「&」を使うことで「複数インターフェイスを実装したクラス」を記述できます。

/**
 * {@link XMLReader}を作成する
 * @param handler SAXハンドラ
 * @return {@link XMLReader}
 * @throws SAXException 
 * @throws ParserConfigurationException
 */
static final <H extends DTDHandler & DeclHandler & LexicalHandler & ContentHandler>
XMLReader createReader( H handler ) 
throws SAXException, ParserConfigurationException {
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setNamespaceAware(true);
    XMLReader r = factory.newSAXParser().getXMLReader();
    r.setContentHandler( handler );
    r.setDTDHandler( handler );
    r.setProperty( "http://xml.org/sax/properties/lexical-handler", handler  );
    r.setProperty( "http://xml.org/sax/properties/declaration-handler", handler  );
    return r;
}

see: http://d.hatena.ne.jp/unageanu/20071022/1193060612


といったところかな。個人的には仕事で普通に使っているので、みかけても引かないでくださいね > 関係者。