Top / Java / TIPS集

あ、これってべんりだなあって思ったコーディングのメモ。

stackTraceを取得する

標準エラーに出力するならe.printStackTrace?()ですが、文字列として取得したい場合は、ストリームにスタックトレースを出力します。

private String exception2String(Exception e) {
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  e.printStackTrace(new PrintStream(baos));
  return baos.toString();
}

文字コードとか大丈夫だっけとかありますが、こんな感じでできます。

プロパティファイルから、複数のデータを配列で取得する

Java Collections Framework の org.apache.commons.collections.ExtendedProperties? を用いると、

上記データにアクセスするサンプルコードは以下の通り。

ExtendedProperties props = new ExtendedProperties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream resourceAsStream = loader
        .getResourceAsStream("hoge.properties");
InputStream in = new BufferedInputStream(resourceAsStream);
props.load(in);
String[] dataArray = props.getStringArray("data");

などとしてデータを取り出すことができます。

パイプされた標準入力を取得する

そういえばJavaって標準入力をどう受け取るんだっけ??ということで調べたメモ。パイプされた標準入力をechoするサンプル。

package nu.mine.kino.mail.utils;

import java.io.BufferedInputStream;
import java.io.IOException;

public class Echo {
    public static void main(String[] args) {
        BufferedInputStream in = new BufferedInputStream(System.in);
        try {
            int size = in.available();
            byte[] bytes = new byte[size];
            in.read(bytes);
            System.out.println(new String(bytes));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

結果はたとえば

[hogehoge@www Test]$ ls  |  java -cp lib/sample.jar nu.mine.kino.mail.utils.Echo
build.win.properties
build_jar.xml
classes
lib
source

[hogehoge@www Test]$

lsの結果を受け取り、echoできました。

ちなみに標準入力を待ち受けてるときに入力完了を通知するための終了文字は Platform-Specific Details: The End-of-Input Character に書いてありました。

参考

Apache Axis 1.4のSSL処理にはバグがありそう

詳しくはまた時間がとれたらにしますが、Basic認証するプロキシサーバ越えでSSL通信するときのAxisの挙動がヘン。Axisが生成する Proxy-Authorizationヘッダの改行コードがおかしい模様。HTTPSの仕様的には、ほんとは\r\nが推奨されるらしいけど\nしかないため、まれに解析に失敗するプロキシサーバがあるようです。

BigDecimal?のコンストラクタにdoubleは使わないほうがいい

ちゃんと数値計算しようと思って、doubleとかの代わりにBigDecimal?を使ってたんだけど、やっぱ誤差が出ちゃう。何でだろーと思ってたら、BigDecimal?のコンストラクタでStringでなくdoubleを使ってたからでした。doubleを引数に取るコンストラクタの方は、引数自体が誤差が出ちゃってるから、正確な計算ができないって事ですね。素直にStringを使ったところ、ビシっと計算が合いました。

って、よく見たらJavaDoc?にも書いてありますね。

mod_proxyを使ってApacheでリバースプロキシを構成する

リバースプロキシはいわゆるDestination NATですね。あるURLにアクセスすると別のサーバにリクエストを転送するヤツです。これで外からのアクセスをファイアウォール内のサーバに転送したり、ラウンドロビンして負荷分散したりできるわけですね。通常のプロキシの逆の流れ(外から内)なので、リバースプロキシと呼ばれています。

mod_proxyを使ってApacheでフォワードプロキシを構成する

フォワードプロキシはいわゆるプロキシサーバですね。社内からインターネットにアクセスするときのゲートウェイですね。

設定は簡単でhttpd.confに以下の記述を追加します。

ProxyRequests On
ProxyVia On

<Proxy *>
  Order deny,allow
  Deny from all
  Allow from 192.168.xx.xx <-接続を許可するホスト
  AddDefaultCharset Shift_JIS
  AuthType Basic <-Basic認証をつける
  AuthName "Test Proxy"
  AuthUserFile  /var/www/conf/.htpasswd
  Require valid-user
</Proxy>

classesディレクトリを一括で削除するワンライナー

rm -rf `find ./ -type d -name classes`

ファイル <-> byte[]に変換するUtil

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;

/*******************************************************************************
 * Copyright (c) 2007 Masatomi KINO. All rights reserved. 
 * $Id$
 ******************************************************************************/
public class Utils {
  public static byte[] file2Byte(String file) throws IOException {
    InputStream in = null;
    byte[] pix = null;
    try {
      in = new FileInputStream(file);
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      byte[] b = new byte[1024];
      int j;
      while ((j = in.read(b)) != -1) {
        baos.write(b, 0, j);
      }
      pix = baos.toByteArray();
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return pix;
  }

  public static void byte2File(byte[] b, String outputFile)
      throws IOException {
    BufferedOutputStream stream = null;
    try {
      File file = new File(outputFile);
      FileOutputStream fstream = new FileOutputStream(file);
      stream = new BufferedOutputStream(fstream);
      stream.write(b);
    } finally {
      if (stream != null) {
        try {
          stream.close();
        } catch (IOException e1) {
          e1.printStackTrace();
        }
      }
    }
  }
} 

整数を16進や2進で表示する

System.out.println(Integer.toHexString(15));
System.out.println(Integer.toBinaryString(15));

実行結果は以下の通り。

f
1111

Base64でエンコードする

Base64とはE-mailなどバイナリデータを使用できない環境で、バイナリデータを扱うためのエンコード方式です*1。バイナリデータをテキストデータに可逆変換します。

Commons Codecを用いれば、バイナリデータを簡単にBase64エンコード可能です。

public class Base64Main {
  public static String encode(String input) {
    byte[] bs = Base64.encodeBase64(input.getBytes(), false); 
                // booleanはある単位で改行を入れるかどうか
    return new String(bs);
  }

  public static void main(String[] args) {
    String string = encode("kino");
    System.out.println(string);
  }
}

実行結果は以下の通り

a2lubw==

簡単ですね。引数にbyte[]を取るので、バイナリファイルからbyte[]を作成し、メソッドに渡してあげればバイナリファイルも簡単にエンコード可能なわけです*2

ちなみにこのCodecライブラリは下に出てくる byte[] -> HexString?な変換をするメソッドなどもあります。

 new String(Hex.encodeHex(b));

とすればOKです。

あ、よく見たらSHA-1でハッシュするメソッドもありました。

System.out.println(DigestUtils.shaHex("kino".getBytes()));

でしたと同じ結果を得ることができます。実行結果は以下の通り。

c108a2616c020deeb71df83906f039e3dfcc6752

おなじですね。

SHA1でハッシュ化

SHA-1はパスワードのハッシュ化などに使われるアルゴリズムです*3

 public static String encrypt(String input) {
   try {
     MessageDigest md = MessageDigest.getInstance("SHA1");
     md.update(input.getBytes("MS932"));
     return toHexString(md.digest());
   } catch (NoSuchAlgorithmException e) {
     e.printStackTrace();
   } catch (UnsupportedEncodingException e) {
     e.printStackTrace();
   }
   return null;
 }
 private static String toHexString(byte[] b) {
   StringBuffer hexString = new StringBuffer();
   String plainText=null;
   for (int i = 0; i < b.length; i++) {
     plainText = Integer.toHexString(0xFF & b[i]);
     if (plainText.length() < 2) {
       plainText = "0" + plainText;
     }
     hexString.append(plainText);
   }
   return new String(hexString);
 }
 public static void main(String[] args) {
   String string = encrypt("kino");
   System.out.println(string);
 }

実行結果は以下の通り。

c108a2616c020deeb71df83906f039e3dfcc6752

SHA1でハッシュ化できました。MessageDigest?.getInstance("SHA1");の「SHA1」を「MD5」にすればMD5でハッシュ化できます。

java.lang.ThreadLocal?について

thlocal.set( new LegacySystemImpl2());
thlocal.set( new LegacySystemImpl());
LegacySystem impl = (LegacySystem) thlocal.get();

などと同じ型のクラスをセットした場合、どうも上書きになるっぽい。ソースを調べた分けじゃないけど。。

http://www.hyuki.com/dp/dpinfo_ThreadSpecificStorage.html#i1

Eclipseのヒープとタスクマネージャの関係

Eclipseのヒープサイズと、タスクマネージャのjavawのメモリ使用量の関係。Eclipseのヒープが

1024M中の500M

とかなってる場合、1024Mの方がタスクマネージャ上に表示される。だから実際どれだけjavaプロセスがメモリを使用しているかはOSからはわからないみたいですね。

EclipseでCVSのブランチを取り扱う。

CVSのトランク(メインっていう?)とブランチをマスターしたくちょっと触ってみました。

まずはバージョンとしてタグ付け。タグ名はたとえば

V20061026_01

とする。次にブランチの作成。チーム >> ブランチ より作成。ブランチ名はたとえば

V20061026_01_BRANCH

とする。そのとき、ブランチをマージするための開始点のタグも併せて登録される。これは自動的に

Root_V20061026_01_BRANCH

というタグ名になる。メインのモジュールにブランチをマージするには、開始点ってのが重要みたいだ。

ここまででCVSには上の3つのタグ

V20061026_01                メイン側
V20061026_01_BRANCH         ブランチ側
Root_V20061026_01_BRANCH    メイン側

ができる。

Eclipseプロジェクトに、メインとブランチ両方落としておく。ブランチの方はプロジェクト名を_branchとかつけとく。

Eclipseで各プロジェクトでソースを修正してコミットする。

メイン側はバージョンは   1.1 -> 1.2 
ブランチ側はバージョンは 1.1 -> 1.1.2.1

となるみたい。

さあ、ブランチからメインへマージします。メインのプロジェクトで、チーム >> マージを選択し

マージされるバージョン(終了タグ) をブランチのバージョン   i.e. V20061026_01_BRANCH 
共通基本バージョン(開始タグ)     をさっきの開始バージョン i.e. Root_V20061026_01_BRANCH

と選択すると、左がメイン、右がブランチのソース比較画面が現れます。適宜Updateすればブランチのソースがメインに取り込まれます。後はメインにコミットすれば、ブランチ分のマージは完了です。

※これはローカルコピーに、開始タグと終了タグの差分を取り出すって事かな?実際ブランチ側でマージしようとしたら、V20061026_01_BRANCH とV20061026_01_BRANCH には差分がないっていう当たり前の表示になってしまった。

実行中のメソッド名を取得する。

new Throwable().getStackTrace()[0].getMethodName();

何故これでメソッド名が取れるんだろう。。。でもうまくいきますねー

byte配列をバイナリに変換する。

逆に、byte[]をファイルに書き出す方法

public static void write(byte[] b) {
  BufferedOutputStream stream = null;
  try {
    File file = new File("after.bin");
    FileOutputStream fstream = new FileOutputStream(file);
    stream = new BufferedOutputStream(fstream);
    stream.write(b);
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    if (stream != null) {
      try {
        stream.close();
      } catch (IOException e1) {
        e1.printStackTrace();
      }
    }

  }
}

バイナリファイルをbyte配列に変換する

Webサービスでバイナリをアップするときなどは、byte[]で渡すみたいです。

public byte[] createBin() {
  InputStream in = null;
  byte[] pix = null;
  try {
    in = new FileInputStream("before.bin"); <-バイナリファイル
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] b = new byte[1024];
    int j;
    while ((j = in.read(b)) != -1) {
      baos.write(b, 0, j);
    }
    pix = baos.toByteArray();
  } catch (IOException e) {
    e.printStackTrace();
  } finally {
    if (in != null) {
      try {
        in.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  return pix;
}

Apache Axisで、プロキシーを越える。

Apache Axisを使ったWEBサービスのProxyクライアントで、HTTPのプロキシー(ややこしい)を越える方法を探していました。

いやあEclipseでソースにブレークポイントつけまくって、探したー。。。。どうやら、

 org.apache.axis.components.net.DefaultHTTPTransportClientProperties

てクラスが、なにやらプロパティをセットしていて、そこがAxisの環境設定値になってる模様。そしてこのクラスは、org.apache.axis.AxisProperties?というjava.util.Properties みたいなのを使っている。ソースを見ると、httpプロキシを越えるためのキー値は

AxisProperties.setProperty("http.proxyHost", "proxyのサーバ名");
AxisProperties.setProperty("http.proxyPort", "proxyのポート番号");
AxisProperties.setProperty("http.proxyUser", "xxxx");
AxisProperties.setProperty("http.proxyPassword", "xxxx");

越えた。。キター。。。

Apache Axisで、自己署名証明書を使用してSSLさせる方法

すげー

HSQLDBの起動、フロントエンドの起動

ブラウザのCookieを手軽に参照する

JavaのTIPではないけど、J2EE開発中によく使うので。ブラウザのURLに

javascript:document.cookie;

と入力すると、クライアントのCookie(今開いているサイトに対するもののみ)を参照できます。

Jakarta Commons Langのいろいろ

Jakarta Commons LangはJavaのライブラリだけでは足りないようなユーティリティ的な機能を提供するクラスライブラリです。たとえば、こんな感じで使うことができます。

フィールドをカプセル化する

設定ファイルとかの場所がフィールドに定数で埋め込まれていて、単体テストのときだけそのパスを変えたいなあなんてときがあります。最近はDIとかで変えれるようにするのがはやってますが、DIコンテナなども使ってないときなどはどうすればよいでしょうか。

例としてテスト対象クラスがHogeだとして

public class Hoge{
  private String path ="hoge/hogehoge.properties";
  .....
  public void exe(){
    new File(path).....;
  }
}

なんてのがあるとき、どうすればよいかってことです。

この場合、まずはソースを変更して単体テストしやすくします。そのソースの変更はEclipseなどを用いて、きっちりやる、と。やる手順は

具体的には上のクラスは以下のように変更します。

ってところですね。。ソースの変更に関してはEclipseなどで論理的に安全に行うことはできますが。手順は、

変数を参照している箇所(new File(path)の"path")を選択して、リファクタリング >> フィールドのカプセル化

定数がフィールドにすらいない場合は、上の前にさらにこれをやる

変数を選択して、 リファクタリング >> ローカル変数を フィールドに変換

プレースホルダを使う

MessageFormat?を使うと、{0}のようなプレースホルダを使うことができます。

SimpleDateFormat yyyy = new SimpleDateFormat("yyyy");
SimpleDateFormat MM = new SimpleDateFormat("MM");
SimpleDateFormat dd = new SimpleDateFormat("dd");
Date selectedDate = new Date();
String year = yyyy.format(selectedDate);
String month = MM.format(selectedDate);
String date = dd.format(selectedDate);
Object[] dateArgs = { year, month, date };
MessageFormat form = new MessageFormat("{0}年{1}月{2}日"); <-プレースホルダ
System.out.println(form.format(dateArgs));

実行結果は

2005年03月18日

e.printStackTrace?()の文字列を取得する、出力先を変更する

例外のインスタンスをexとして

StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
String message = stringWriter.getBuffer().toString();

WSAD5.1.2でサーバの設定が格納されているディレクトリ

${WORKSPACE}\.metadata\.plugins\com.ibm.wtp.server.core\configs

プロクシ認証などなど

-Dhttp.proxyHost=[プロクシサーバ名] -Dhttp.proxyPort=[ポート番号]
-Dhttp.proxyUser=[UserID] -Dhttp.proxyPassword=[password]

privateなフィールドにアクセスする

たとえばインスタンス名instance のフィールド(Stringで変数名aField)にアクセスするには

Class clazz = instance.getClass();
Field field = clazz.getDeclaredField("aField");
field.setAccessible(true);
String answer = (String)field.get(instance));

で取得できる。ここが参考になりました。

<%@ page %> タグ内の意味。

たとえば

<%@ page contentType=text/html; charset=EUC-JP" pageEncoding="Shift_JIS" %>

とした場合、pageEncodingがソースコードの文字コード、contentTypeで指定できるのが出力文字コードです*4。この場合はソースをShift_JISで書いて、EUC-JPで出力するってことですね。

key=value&...の形式ではないPOSTリクエストの電文を取得する方法

requestからReaderを取得して、そこから文字を取得すればよいわけですね。

BufferedReader reader = request.getReader();
StringBuffer buffer = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
  buffer.append(URLDecoder.decode(line));
  buffer.append("\n");
}
String reqMsg = new String(buffer);

DOM2String

ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
  TransformerFactory tfactory = TransformerFactory.newInstance();
  Transformer transformer = tfactory.newTransformer();
  transformer.setOutputProperty("encoding", encoding);
  transformer.transform(new DOMSource(document), new StreamResult(out));
} catch (TransformerConfigurationException e) {
  logger_.error(e);
} catch (TransformerException e) {
  logger_.error(e);
}
return out.toString();

String2DOM

例外処理はとりあえずおいといて

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
StringReader stringReader = new StringReader(str); <- str: xmlの文字列
InputSource inputSource = new InputSource(stringReader);
return builder.parse(inputSource); <- Document

ファイル書きだし(バイナリで)

InputStream in = .....;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int j;
while ((j = in.read(b)) != -1)
    baos.write(b, 0, j);
byte[] pix = baos.toByteArray();
write("hoge.dat", pix);

private void write(String filename, byte[] b) {
    BufferedOutputStream stream = null;
    try {
        File file = new File(DictionariesPlugin.getDefault()
                .getStateLocation().toFile(), filename);
        FileOutputStream fstream = new FileOutputStream(file);
        stream = new BufferedOutputStream(fstream);
        stream.write(b);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }

    }
}

ファイル書きだし(テキスト)

public boolean write(String log) {
  BufferedWriter writer = null;
  try {
    //第二引数がtrueなら追記、falseなら上書き。
    writer = new BufferedWriter(new FileWriter("./log.txt", true));
    writer.write(log, 0, log.length());
    writer.newLine();
  } catch (FileNotFoundException e) {
    e.printStackTrace();
    return false;
  } catch (IOException e) {
    e.printStackTrace();
    return false;
  } finally {
    try {
      if (writer != null) {
        writer.flush();
        writer.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  return true;
}

あるディレクトリからの相対パスを計算して、他のディレクトリに連結したい。

うまく説明できませんが、別のディレクトリに同じパス構成をコピーしたいときなどに使用できると思います。

 //たとえば "c:/temp", "c:/temp/fuga/aaaaa.txt", "d:/huge/hoho" に対して
 // d:/huge/hoho/fuga/aaaaa.txt としたい
 public static String trimAndConcat(String base, String path, String other) {
   URI uriBase = new File(base).toURI();
   URI uriPath = new File(path).toURI();
   URI uriRelativised = uriBase.relativize(uriPath);
   return new File(other, uriRelativised.toString()).getAbsolutePath();
 }

URLからファイルパスへ。

URLクラスからそのファイルまでのパスを取得する方法です。

String path = new File(url.getPath()).getPath();

とやることで、

URL : file:/C:/hoge/config/hoge.txt
File: C:\hoge\config\hoge.txt

に変換ができます。*5*6

(たとえば)拡張子がxmlのファイルをリストする

File mainDirectory = new File([ディレクトリ]);
String[] files = mainDirectory.list(new FilenameFilter() {
  public boolean accept(File dir, String name) {
    if (name.endsWith("xml")) {
      return true;
    }
    return false;
  }
});

filesが拡張子がxmlのファイル(ファイル名、の配列)

拡張子より後ろの文字列を取得する

String hoge="aaa.xml";
hoge.substring(hoge.lastIndexOf('.'));

で.xmlが取得できる。

拡張子より前の文字列を取得する

String hoge="aaa.xml";
hoge.substring(0, hoge.indexOf('.'));

でaaaが取得できる。/etc/aaa.xml.bakとかには使えないけど。。

Javaから、WEBブラウザを起動(Windowsのみ)

try {
	Runtime.getRuntime().exec(
		new String[] {
			"rundll32.exe",
			"url.dll,FileProtocolHandler",
			"http://jp.sun.com/" });
} catch (IOException e) {
	e.printStackTrace();
}

SWTから起動したい方は こちら

WEBアプリケーションのルートを取得してパスを生成する

String root_path = this.getServletContext().getRealPath("/");
String file_path = root_path + "hoge.dat"

DOMオブジェクトをファイルに書き出す

try {
	TransformerFactory tfactory = TransformerFactory.newInstance();
	Transformer transformer = tfactory.newTransformer();
	//			transformer.setOutputProperty("encoding", "EUC-JP");
	transformer.transform(new DOMSource(document), <-document : XMLのDOMです
	//new StreamResult(System.out)); <- こっちだとコンソール出力
	new StreamResult(new FileOutputStream(new File(output))));

} catch (TransformerConfigurationException e) {
	e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
	e.printStackTrace();
} catch (TransformerException e) {
	e.printStackTrace();
} catch (FileNotFoundException e) {
	// TODO 自動生成された catch ブロック
	e.printStackTrace();
}

JSPやServletのOutにDOMを書き出したい。

public void write(HttpServletRequest request, HttpServletResponse response) {
	response.setContentType("text/xml; charset=UTF-8");
	try {
		PrintWriter out = response.getWriter();
		transformer.transform(new DOMSource(getDocument()),
		new StreamResult(out));
	} catch (IOException e) {
	} catch (TransformerException e) {
	}
}

Servletで、コンテンツタイプを指定する。

response.setContentType("text/xml; charset=UTF-8");

プロキシ越えとか、HttpConnection?

fileplain&root=cvs
//プロキシ認証の記述方法
BASE64Encoder encoder = new BASE64Encoder();
urlConnection.setRequestProperty(
 "Proxy-Authorization",
 "Basic " + encoder.encode((userid + ":" + password).getBytes()));

javaの実行

>java -classpath ".;lib;classes;lib\log4j-1.2.8.jar;swt.jar" kino.swt.JavaDocSearchForm
>java -classpath ".;lib;classes;lib\log4j-1.2.8.jar;swt.jar;lib\kino_javadocsearch.jar" 
 kino.swt.JavaDocSearchForm
>java -classpath "クラスパス(セミコロン区切り)" クラス

このサイトよいかも。

Javadoc書き方

@see	UserInformationManager#getUserInformation(String)

とすると、リンクが張られる。

{@link	InformationController	InformationController}のファイル読み込みの実装です。

とか

{@link クラス名#メンバ名 表示テキスト}

なんて使い方もできる

コレクションを配列に変換

type: 型
collection: コレクションクラス
(type[]) collection.toArray(new type[collection.size()]);

配列をコレクションに変換

fileList: Object[]型
java.util.Arrays.asList(fileList);

ファイルを読み込む

BufferedReader reader = null;
try {
	reader = new BufferedReader(new FileReader(path));
	//もしくは
	//new BufferedReader(
	//  new InputStreamReader(url.openStream(), "JISAutoDetect"));
  
	String line;
	while ((line = reader.readLine()) != null) {
		buffer.append(line);
		buffer.append("\n");
	}
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
} finally {
	if (reader != null) {
		try {
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		reader = null;
	}
}

Objectのシリアライズ

try {
	//FileInputStreamオブジェクトの生成
	FileInputStream inFile =
		new FileInputStream([serializeしたファイル名]);

	//ObjectInputStreamオブジェクトの生成 
	ObjectInputStream inObject = new ObjectInputStream(inFile);

	Object object = (クラス名) inObject.readObject();

	inObject.close(); //オブジェクト入力ストリームのクローズ
	inFile.close(); //ファイル入力ストリームのクローズ

	//FileOutputStreamオブジェクトの生成
	FileOutputStream outFile =
		new FileOutputStream([書き出したいファイル名]);

	//ObjectOutputStreamオブジェクトの生成 
	ObjectOutputStream outObject = new ObjectOutputStream(outFile);

	//クラスVectorのオブジェクトの書き込み
	outObject.writeObject(object);

	outObject.close(); //オブジェクト出力ストリームのクローズ
	outFile.close(); //ファイル出力ストリームのクローズ

} catch (FileNotFoundException e) {
} catch (IOException e) {
} catch (ClassNotFoundException e) {
}

オブジェクトが配列かどうかをチェックする

String model = "hogehoge";
// String[] model = new String[] { "hogehoge", "hugahuga" };

List list = new ArrayList();
if (model.getClass().isArray()) {
    Object tmp = model;
    list = Arrays.asList((Object[]) tmp);
} else {
    list.add(model);
}
System.out.println(list);

インナクラス、無名クラス

インナークラス・無名クラスは、フィールドにはアクセス可能、ローカル変数には不可能。

finalなフィールドの初期化

宣言時に初期化する必要があるのかと思ってたんですが、コンストラクタ内でもよいんですね。知らなかった。


この記事は

選択肢 投票
おもしろかった 36  
そうでもない 8  

Top / Java / TIPS集

現在のアクセス:129673


*1 http://ja.wikipedia.org/wiki/Base64
*2 なぜ戻り値がbyte[]なのかは不明
*3 http://ja.wikipedia.org/wiki/SHA
*4 JSP1.1の場合は、pageEncoding が使えないので、ページの文字コードと出力文字コードは同じになります。
*5 URLクラスをそのままtoStringすると、よけいな文字(file)がついちゃうんですよね。
*6 スペースなどが入っている場合のために、URLDecoder#decodeをかけねばっ

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS