Java basic language
戻る LastUpdate:JAVA逆引き
http://www.stackasterisk.jp/tech/javaClassref/index.jsp
Javaの道
http://www.javaroad.jp/index_basic.htm
JavaDrive
http://www.javadrive.jp/start/index.html
001 基本的なコンパイル&実行
002 システムアウトの例
003 Java基本の型
004 String 型クラスの使い方
005 アクセス制御レベル
006 例外処理
007 インナークラスって何?
008 サーブレットから日本語をブラウザに表示するには?
009 ハッシュテーブルって何?
010 全てのシステムプロパティを取得
011 プロパティファイルを読み込む例
012 システムプロパティの追加の方法
013 Listクラス系のコーディングサンプル
014 Mapクラス系のコーディングサンプル
015 どうしてもわからん=よくやる失敗
016 各種宣言の仕方
017 数字と文字の変換
20050110 配列型の使用
20050202-1 JDBC 列の項目がNULLかどうかを判定する方法は?
20050303-1 タイマーで一定間隔で処理を動かす方法は
20050307-1 クラスパスを取得する方法
20050309 ソケットを使ったサンプル
20050316 定数 リテラル 固定変数の切り方
20050329 実在日の判定ロジック
20050330 DATE型から、年月日の取りだし
20051019 システム日付を取得する
20050512 list内部のObjectの配列からメンバの配列に変換したい時
20050614 クラスの動的ロード
20050805 外部EXEの起動
20050809 文字列連結 StringBuffer String
20050811 メールを送る
20051007 数値のフォーマット
20080311 日付のフォーマット
20080331 Integer型の比較
20090401_C言語のprintfが使えるようになった
20090401_外部PGのデバッグ_ができるか
20090504_プロパティファイルを用いた、クラスの動的ロード例
20090614_JDBC基本サンプル
20090619_無名パッケージのクラスは、名前付きパッケージから使えない
20090625_スレッド単位に変数を取り回す方法
20090629_アノテーション
20090701_JAXB_XMLスキーマを使わずにバインド
20090715_Mapのキーに_自分で作成したクラスを用いた場合の留意点
20090720_synchronized_のまとめ
20090725_loggingについて
20090730_シリアライズ
20090731_Mapのソート
20090811_File_Folder_の_helperクラス
20090811_総称型_GENERIC型_の例
20090811_外部コマンドの実行
20091031_JAXB_XML_パースエラー:_整形式になっていません。_
20100227_JDBC_DATE型
20100301_StringBuffer_と_StringBuilder
20100310_enum型
ファイル名:HelloWorldapp.java
// HelloWorldapp.java
class HelloWorldapp {
public static void main(String args[]){
System.out.println("Hello World!");
}
}
c:\test>javac HelloWorldapp.java ←コンパイル
c:\test>java HelloWorldapp ←実行
Hello World! ←実行結果
System.out.println("abcde");
System.out.println("fghij"); ←改行される
---------------------
abcde
fghij
System.out.print("abcde");
System.out.print("fghij"); ←続けて表示される
---------------------
abcdefghij
データ型 |
サイズ |
表現できる値 | |
整数 | byte | 8 ビット | -128 〜 127 |
short | 16ビット | -32,768 〜 32,767 | |
int | 32ビット | -2,147,483,648 〜 2,147,483,647 | |
long | 64ビット | -9,223,372,036,854,775,808 〜 9,223,372,036,854,775,807 | |
浮動小数 | float | 32ビット | IEEE754に基づく浮動小数点 |
double | 64ビット | IEEE754に基づく浮動小数点 | |
文字 | char | 16ビット | Unicode で 表現できる 1文字 |
論理値 | boolean |
- |
true / false |
メソッドの中の単なるローカル変数として宣言した場合は、中の値が初期化されていない。初期化されていない変数を参照するようなコーディングをした場合は、コンパイルエラーになる。
しかし、クラスの変数とした場合は、初期値が格納されている。
上記の表以外は、全てクラスで提供される。String 型
は定義しなくても使える組み込みのクラスである。
String型の変数は、クラス変数とした場合、初期値はnullが格納されている。
String型は、VC++のstring型に極めて近いものである。
//宣言
String str1System.out.println("abcde");
System.out.println("fghij"); ←改行される
---------------------
abcde
fghij
System.out.print("abcde");
System.out.print("fghij"); ←続けて表示される
---------------------
abcdefghij
クラスで宣言されたメソッドやメンバ変数のアクセス可能な範囲について示す。
private | キーワード無し | protected | public | |
同一のパッケージに属するクラス間でのアクセス | × | ○ | ○ | ○ |
継承関係にあるクラス間でのアクセス | × | × | ○ | ○ |
異なるパッケージに属するクラス間でのアクセス | × | × | × | ○ |
private宣言されたものは同一クラス内からしかアクセスできなくなる。(ほんとかな〜)
C++のように、クラスを継承する時には使用できないようです。コンパイルエラーになる
//人間クラス
class Human{
Human(){
}
}
//男クラス
class Man extends /*protected*/ Human{
Man(){
}
}
2001/11/18
フィールドなどのスコープ例外用のクラスとして、java.lang.Throwable
が提供されている。このクラスから派生した重要な3つのクラスについて
Throwableクラス
例外処理用に提供されるクラスのスーバークラス。このクラスはユーザーレベルでは使用不可。
Errorクラス
メモリ不足などのハード的なエラーが発生した時にあげられる。この例外に対する処理は任意。
補足:
Javaの内部システムの異常で、アプリケーションではどうしようもない。よって、アプリ側での対処は必須ではない。
Exceptionクラス
プログラムで問題が発生した場合、その問題がシステム的に重大な問題では無いことを表す。このクラスの多くはサブクラスを持ち、各サブクラス発生する種々の例外の型を示す。この例外に対する処理は必須である。
RuntimeExceptionクラス
プログラム実行時に発生した例外である事を表す。この例外に対する処理は任意である。
補足:
配列の領域外などバグでしかありえないような事を扱う。このような事はアプリケーションでいちいち処理する事は過激なので、対処は任意扱いとされている。
(もし、ゼロ割りが発生したらどうする?...なんて事を全てのメソッドで実装していたら、タマランですね。)
throws 例外オブジェクト
try {
....
throw 例外オブジェクト;
} catch (例外用クラス a){
....
} catch (例外用クラス b){
....
} finally {
例外の有無に関係なく、実行される
}
自分のメソッド内で呼び出すメソッドが例外を通知する場合、何らかの処理をしなくてはならない。
catchして自分で処理してもいいし、ただ、throws Exception
をメソッドの宣言につければ、さらに呼び元のメソッドに例外処理を委譲することができる
下位のメソッドで、エラーが発生した時、上位でメッセージを加えてスローし直す時は、このようにすれば、メッセージがひきつがれるので便利
try { ・・・処理 } catch (Exception e) { throw new Exception(エラーメッセージ , e); }
java.lang.Exception: XMLファイルにエラーが発生しました:C:\data\java\20050312_固定長ファイルのパース\bbb.xml
at uxx.file.FixedLengthRecordParser.(FixedLengthRecordParser.java:100)
at Main.main(Main.java:26)
Caused by: java.lang.Exception: 項目に英名が設定されていません
at uxx.file.FixedLengthRecordParser.makeFileds(FixedLengthRecordParser.java:167)
at uxx.file.FixedLengthRecordParser.(FixedLengthRecordParser.java:94)
... 1 more
これから詳しく覚えていく必要があるな〜。まずは下記参照
http://www.gimlay.org/~javafaq/S016.html
クラスの中にクラスを切れる。内部のクラスは、外側のインスタンスの中のインスタンスになる。つまり外側のインスタンスが生成されていないと中側のクラスは存在できない。外側のクラスをエンクロージングインスタンスという。内部のクラスをstatic宣言すると、外側のインスタンスが存在しなくても内側のインスタンスが存在できる事になる。
以下の例は、doGetメソッド部分のみの抽出である。
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
processRequest(request, response);
response.setContentType("text/html;charset=EUC_JP");
java.io.PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<meta http-equiv='Content-Type' content='text/html; charset=EUC_JP'>");
out.println("<title>Servlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>あいうえお</p>");
out.println("</body>");
out.println("</html>");
out.close();
}
こうすればうまくいく。
サーブレットはJavaなのでUnicodeとしてコンパイラは処理を行なう。開発マシンのコードが何であっても、あいうえおは、Unicodeとして扱ってくれるが、ブラウザに送りつけるときにどのようにエンコードすれば良いか、サーブレットエンジンは知らない。そこで、
response.setContentType("text/html;charset=EUC_JP")
を指定することにより、エンコードタイプを強制できることになる。
ブラウザ側は、送られてきたコードを何でエンコードすればいいかを指定してやる方法が
out.println("<meta http-equiv='Content-Type' content='text/html; charset=EUC_JP'>");
である。私はこれをパソコンベースで全ておこなった。
このソースの場合、IEは、エンコード指定がなんであっても meta タグで EUCと指定されているのでバッチリ表示された。
METAタグを指定しなかった場合、SJISの解釈をして、文字化けしたが、IEでエンコード指定したら正しく表示された。
response.setContentType("text/html");のように、サーブレット側でエンコードを指定しなかったときは、インフラのコード体系に則るらしいが、ブラウザでどのように設定しても正しく表示されなかった。サーブレットエンジンの設定もあるのかもしれない。
LinuxでJAVAサーブレットを開発する際の日本語処理の注意点について.mht
2001/12/07
そもそもハッシュとは、データを無理矢理 数値に変換するもののようです。で、どんなメリットがあるかというと名前がキーになっているテーブルを検索するときに、名前で検索したらひとつひとつ順に読んで行かなくてはいかないけど、ハッシュにより名前を数値に置き換えてそれを10で割ったあまりを求めると、かならず、名前が1〜10のグループに分けれられるわけね、そのグループ単位で登録しておくと、検索するときにも同じようにハッしゅで数値を出して10で割った余りを求めると、どこのグループかが判る。よって、全部探さなくても、そのグループ内だけ探せばみつかる。つまり、早く見つけるための仕掛け・に応用できるということのようです。
http://www.mars.dti.ne.jp/~torao/program/structure/hash.html
もうすこし詳しく書いてあるところ
http://www.gimlay.org/~javafaq/S038.html
2001/12/07
もう少し元の意味から書いてあると思われるページです
http://www.geocities.co.jp/SiliconValley-PaloAlto/1037/tables3.html
2002/12/27
system propertyの話
public class ShowSystemProperties {
public static void main(String[] args) {
System.getProperties().list(System.out);
}
}
実行結果
>java ShowSystemProperties
-- listing properties --
java.runtime.name=Java(TM) 2 Runtime Environment, Stand...
sun.boot.library.path=C:\jdk1.3\jre\bin
java.vm.version=1.3.0_02
java.vm.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
path.separator=;
java.vm.name=Java HotSpot(TM) Client VM
file.encoding.pkg=sun.io
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\data\java\20011218_プロパティを全て見る
java.runtime.version=1.3.0_02
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
os.arch=x86
java.io.tmpdir=C:\DOCUME~1\WATANA~1.000\LOCALS~1\Temp\
line.separator=
java.vm.specification.vendor=Sun Microsystems Inc.
java.awt.fonts=
os.name=Windows 2000
java.library.path=C:\jdk1.3\bin;.;C:\WINNT\System32;C:\...
java.specification.name=Java Platform API Specification
java.class.version=47.0
os.version=5.0
user.home=C:\Documents and Settings\watanabe-s....
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=MS932
java.specification.version=1.3
user.name=watanabe-s
java.class.path=.;"C:Program Files\Allaire\JRun\lib\e...
java.vm.specification.version=1.0
java.home=C:\jdk1.3\jre
user.language=ja
java.specification.vendor=Sun Microsystems Inc.
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode
java.version=1.3.0_02
java.ext.dirs=C:\jdk1.3\jre\lib\ext
sun.boot.class.path=C:\jdk1.3\jre\lib\rt.jar;C:\jdk1.3\jr...
java.vendor=Sun Microsystems Inc.
file.separator=\
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport...
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
user.region=JP
sun.cpu.isalist=pentium i486 i386
2001/12/18
http://www.dmz.hitachi-sk.co.jp/Java/Tech/api/resource.html
リソースは形式を問わないファイルですが、プロパティは「名前=値」という形式が決まっているファイルです。
プロパティファイルも、リソースと同じように、プロパティファイル名を指定するとクラスパス上から自動的に検索して読み込んでくれます。
ただし、プロパティファイル名はリソースの「/」区切りと違って、「.」を使って、クラス名とそっくりな書き方をします。
さらに、プロパティ名をキーとしてプロパティ値を取得することができます。
次のサンプルは、「resdir.myres」というプロパティファイルから「key1」という名前のプロパティ値を取り出すものです。
import java.util.*; public class GetProperty { public static void main(String args[]) { try { /* resdir.myresという名前で指されるプロパティファイルを取り出す */ ResourceBundle bundle = ResourceBundle.getBundle("resdir.myres"); String val = bundle.getString("key1"); System.out.println(val); } catch (Exception ex) { ex.printStackTrace(System.err); } } }
プロパティファイルは「resdir\myres.properties」という名前で、次のようなフォーマットで作っておきます。
resdir は パッケージ名の扱いになります。
myres が、クラス名と同等の位置づけになります。
したがって、クラスパスのトップから、 /resdir/myres になります。
key1=value1 key2=value2
ただし、この「ResourceBundleクラス」を使った場合は、プロパティ値は読み込み専用で、新規追加や更新はできません。新規追加・更新をしたいときは、「Propertiesクラス」を使います。
こちらは、プロパティファイル名をフルパスで指定しなければなりませんが、更新した値を好きなファイルにセーブすることができます。
import java.util.*; import java.io.*; public class GetProperty { public static void main(String args[]) { try { /* プロパティファイルのパスを渡して読み込む */ Properties prop = new Properties(); prop.load(new FileInputStream("resdir/myres.properties")); String value = prop.getProperty("key1"); System.out.println(value); prop.setProperty("key3","value3"); /* 更新後のプロパティを別のファイルに保存する */ prop.store(new FileOutputStream("resdir/myres_stored.properties"),"Stored by GetProperty"); } catch (Exception ex) { ex.printStackTrace(System.err); } } }
2001/12/18
ファイルパス、ファイル名、拡張子にとらわれず、情報を取得する事もできる
public static void main(String[] args) { Properties prop = new Properties(); try { prop.load(new FileInputStream("P:/data/java/eclipse_workspace/20090706 プロパティファイルの読み込み/data/ppp.dat")); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } String value = prop.getProperty("key1"); System.out.println(value); }
これらのプロパティ値は、MAP系テーブルにキャッシュされているようだ
2009/07/06
プロパティファイルに漢字が含まれる場合は、ユニコード変換を行う必要あり(〜1.5まで?)
../environment/environment.html#20090722_native2ascii
複数のプロパティファイルをひとつに見せかけて行う方法
SequenceInputStream クラスを用いれば良い
二つの場合FileInputStreamの場合
try { InputStream inputStream1 = new FileInputStream( "P:/data/java/eclipse_workspace/20090706 プロパティファイルの読み込み/data/ppp.dat"); InputStream inputStream2 = new FileInputStream( "P:/data/java/eclipse_workspace/20090706 プロパティファイルの読み込み/data/qqq.dat"); InputStream inputStream = new SequenceInputStream(inputStream1,inputStream2); Properties prop = new Properties(); prop.load(inputStream); String value; value = prop.getProperty("key3"); System.out.println(value); value = prop.getProperty("key6"); System.out.println(value); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
三つ以上の場合
try { InputStream inputStream1 = new FileInputStream( "P:/data/java/eclipse_workspace/20090706 プロパティファイルの読み込み/data/ppp.dat"); InputStream inputStream2 = new FileInputStream( "P:/data/java/eclipse_workspace/20090706 プロパティファイルの読み込み/data/qqq.dat"); InputStream inputStream3 = new FileInputStream( "P:/data/java/eclipse_workspace/20090706 プロパティファイルの読み込み/data/rrr.dat"); Vector<InputStream> inputStreamList = new Vector<InputStream>(); inputStreamList.add(inputStream1); inputStreamList.add(inputStream2); inputStreamList.add(inputStream3); Enumeration<InputStream> en = inputStreamList.elements(); InputStream inputStream = new SequenceInputStream(en) ; Properties prop = new Properties(); prop.load(inputStream); String value; value = prop.getProperty("key3"); System.out.println(value); value = prop.getProperty("key6"); System.out.println(value); value = prop.getProperty("key12"); System.out.println(value); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
よく、システムプロパティにxxxを追加とあるが、どういう意味か?
#010の例でもあるように、javaVMに対するプロパティに追加するという意味である。
追加の仕方は簡単で、javaコマンドに対して以下のように行なう。
java -DAddProperty="abcde" ShowSystemProperties
システムプロパティに プロパティ名 AddProperty とう名前で 値”abcde” を追加した例である。
実行結果は
-- listing properties --
java.runtime.name=Java(TM) 2 Runtime Environment, Stand...
AddProperty=abcde
sun.boot.library.path=C:\jdk1.3\jre\bin
java.vm.version=1.3.0_02
java.vm.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
path.separator=;
java.vm.name=Java HotSpot(TM) Client VM
file.encoding.pkg=sun.io
java.vm.specification.name=Java Virtual Machine Specification
...以後省略...
JRunでのシステムプロパティの追加の方法
TomCatでのシステムプロパティの追加の方法
2001/12/26
import java.util.*;
class ArrayList_Test {
public static void main(String args[]){
// リンクテーブルのインスタンスを作成する。
ArrayList list = new ArrayList();
System.out.println("list.size()=>" + list.size() ) ;
// 要素を追加してみる
list.add("data1");
list.add("data3");
list.add("data2");
list.add("data4");
System.out.println("list.size()=>" + list.size() ) ;
Iterator iterator = list.iterator();
while (iterator.hasNext()){
Object rec = iterator.next();
System.out.println("rec=>" + rec ) ;
}
// キーの有無判定
System.out.println("list.contains(data4)=>" + list.contains("data4"));
System.out.println("list.contains(data5)=>" + list.contains("data5"));
}
}
2002/02/07
イテレータの使い方の基本
Iterator<String> iterator = filedNameSet.iterator();
while (iterator.hasNext()) {
String filedName = iterator.next();
}
2005/04/27
List系のエレメントに対して、自由にソートをする場合は、collections.sort を使用すれば良いようだ。
java/basic_language/20090823_collection_zu/class_zu.pdf
import java.util.*;
class map_Test {
public static void main(String args[]){
// ハッシュテーブルのインスタンスを作成する。
HashMap map = new HashMap();
System.out.println("map.size()=>" + map.size() ) ;
// 要素を追加してみる
map.put("key1","data1");
map.put("key2","data2");
map.put("key3","data3");
map.put("key4","data4");
map.put("key2","data02"); // 上書き
// 要素を取り出してみる
System.out.println( "key1=>" + map.get("key1"));
System.out.println( "key2=>" + map.get("key2"));
System.out.println( "key4=>" + map.get("key4"));
// キーの有無判定
System.out.println("map.containsKey(key4)=>" + map.containsKey("key4"));
System.out.println("map.containsKey(key5)=>" + map.containsKey("key5"));
}
}
2002/02/07
LinkedHashMap | 登録順序を保持する |
TreeMap | 登録したキーがソートされて格納される |
IdentityHashMap | キーの同一性を判定する際に、キーに指定されたオブジェクトの実体を比較する |
WeakHashMap | キーが参照されない状態になると、その値がガーベジ・コレクションの対象になる |
NullPointerException 編
ちゃんとNewしてるじゃないか!
あら、型をつけてnewしてると、別の変数になってしまってますね。
Object aa;
{
Object aa = new Object();nullかどうかデバッグプリントをいれてみたら、おちちゃった
System.out.println( targetClass ); これはOK
System.out.println( targetClass.toString() ); これはダメ。NULLポインタにメソッドは動かせません。
フィールド
[修飾子] 型 変数名 ;
修飾子 | 意味 |
public | どこからでも、この変数を使用できる。 |
protected | 変数を定義しているクラス 同一パッケージ内のクラス サブクラスから、使用できる。 |
キーワードなし | 変数を定義しているクラス、 同一パッケージ内のみ、使用できる。 |
private | 変数を定義しているクラスからのみ、使用できる。 |
static | クラスに対し、ひとつだけ存在する変数となる。 |
final | 一度代入した値は、変更できない。 |
メソッド
[修飾子] 型 メソッド名([引数]) [throws 例外クラス] {
[処理;]
}
修飾子 | 意味 |
public | 外部クラスから使用できる。 |
protected | このクラス 同一パッケージクラス サブクラスから、使用できる。 |
キーワードなし | このクラスと 同一パッケージクラスから、使用できる。 |
private | このクラスからのみ、使用できる。 |
abstract | 抽象メソッドである。中身は定義されていない。 |
final | このメソッドを、オーバーロード、オーバーライドできない。 |
static | クラスに対し、ひとつだけ存在するメソッドとなる。 |
native | このメソッドは、Java言語以外の言語で実装される。? |
synchronized | このメソッドは、同一オブジェクト内では、ひとつしか動作しない。(シンクロする。) |
2002/02/26
//数字から文字列への変換
str = String.valueOf(ix);
//文字から数字への変換
int = Integer.parseInt(String);
2002/05/02
int[] i ; →こうも書ける int i [];
i = new int[5];
System.out.println(i.length);
配列は配列型の変数となります。newをしなくては使えません。Cとは異なります。
lengthプロパティにより、メンバ数が取得できます。 この例の場合は5が返ります。
Class.forName(String className
)
クラスのローディングはこのメソッドが実行された時に行われます。
クラス名.class
プログラムの開始時に目的のクラスがローディングされます。
ex) Class type = String.class;
ちなみに、
Class.newInstance()は、クラスが示す、クラスのインスタンスをobject型で生成・返却します。
20090504_プロパティファイルを用いた、クラスの動的ロード例
resultSet#getXXX() を行った後、 resultSet#wasNull() を行なう。
なんでisNull みたいな前判定が無いのじゃ?
JDK のドキュメントによると、以下のように書かれています。
---- ここから ----
A.9 isNull と wasNull
SQL の NULL を処理するよい方法の決定までには、若干の困難がありました。しかし、JDBC 0.50 では、十分に使いやすいと思われるResultSet.isNull メソッドが提供されました。列を読み取る前、または読み取ったあとに isNull メソッドを呼び出して、列がNULLかどうかを判定できます。
if (!ResultSet(isNull(3)) {
count += ResultSet.getInt(3);
}
残念ながら、isNull をすべてのデータベースに確実に実装するのは不可能であることが明らかになりました。一部のデータベースでは、列を読み取る以外に列が NULL かどうかを判定する手段がなく、しかも特定の列の読み取りは 1 回しか認められていません。
列の値を読み取り、あとで使えるように保存しておく方法を検討しましたが、データの変換が必要な場合に問題があります。
さまざまな解決策を調査したあと、不本意ながら、isNull メソッドを wasNull メソッドに置き換えることに決定しました。wasNull メソッドは、単に、特定の ResultSet (または CallableStatement) から読み取った最後の値が SQL の NULL かどうかだけを返します。
スレッド切って、そのスレッドをタイマー実行します
------------------------------------------------Mian.java import java.util.Timer; /* * 作成日: 2005/03/01 * * この生成されたコメントの挿入されるテンプレートを変更するため * ウィンドウ > 設定 > Java > コード生成 > コードとコメント */ /** * @author sp0058 * * この生成されたコメントの挿入されるテンプレートを変更するため * ウィンドウ > 設定 > Java > コード生成 > コードとコメント */ public class Main { public static void main(String[] args) { MyJob myJob = new MyJob(); Timer timer = new Timer(); timer.scheduleAtFixedRate(myJob,0,1000); System.out.println("scheduleAtFixedRate を起動した"); try { System.out.println("メインスレッド5秒停止開始"); Thread.sleep(5000); } catch (InterruptedException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } System.out.println("メインスレッド5秒停止完了"); timer.cancel(); System.out.println("タスク終了"); System.out.println("メイン処理を終了"); } }
------------------------------------------------MyJob.java import java.util.TimerTask; /* * 作成日: 2005/03/01 * * この生成されたコメントの挿入されるテンプレートを変更するため * ウィンドウ > 設定 > Java > コード生成 > コードとコメント */ /** * @author sp0058 * * この生成されたコメントの挿入されるテンプレートを変更するため * ウィンドウ > 設定 > Java > コード生成 > コードとコメント */ public class MyJob extends TimerTask { static long count; public void run() { // TODO 自動生成されたメソッド・スタブ System.out.println(count++); } }
String classPath = System.getProperty("java.class.path");
引数にいれる文字列は、010 全てのシステムプロパティを取得 を参照
private static final String TEST_NOUFU_SELECT = "AAAA" ;
/** 日付の実在日チェックを行う * @param i_yearS 西暦年 * @param i_month 月 * @param i_day 日 * @return */ public boolean checkDateValue(int i_yearS, int i_month, int i_day) { //GregorianCalendarを利用して行う GregorianCalendar calendar = new GregorianCalendar(); //厳密な日付チェックを行う calendar.setLenient(false); calendar.set(i_yearS, i_month - 1, i_day); try { Date date = calendar.getTime(); return true; } catch (IllegalArgumentException e) { return false; } }
Calendar calender = Calendar.getInstance(); calender.setTime(date); int year = calender.get(Calendar.YEAR); int month = calender.get(Calendar.MONTH) + 1; int day = calender.get(Calendar.DAY_OF_MONTH);
下記のようなコーディングをすると、キャストエラーが発生する
Oya[] oyas = (Oya[])list.toArray();
理由は、Oya[ ] と Object[ ] に継承関係が無いからである。
このような事をしたい時は、以下のようにすれば良い。
Oya[] oyas = new Oya[list.size()]; System.arraycopy(list.toArray(),0,oyas,0,list.size());
使用するクラス名を外部ファイルから指定するなどして、実装時に決定できない時は クラスのロードにより行う。
Class class = Class.forName("testPackage.TestClass"); Object object = class.newInstance(); TestSuperClass testSuperClass = (TestSuperClass)object;
20090504_プロパティファイルを用いた、クラスの動的ロード例
//メモ帳を起動してみる Runtime runtime = Runtime.getRuntime(); try { Process process = runtime.exec("C:/WINDOWS/system32/notepad.exe"); //起動ができたら、次へ進みます System.out.println(process); } catch (IOException e) { e.printStackTrace(); }
終了を監視するように変更してみよう
public class Start { public static void main(String[] args) { try { Job job = new Job("C:/WINDOWS/system32/notepad.exe"); job.start(); for (int i = 0; i < 10; i++) { Thread.sleep(1000); if (job.isTerminated()) { System.out.print("終了"); System.out.println(job.getTerminatedCode()); } else { System.out.println("起動中"); } } job.destroy(); job.destroy(); // 終了しているのに、終了させても大丈夫だ System.out.println(job.getTerminatedCode()); } catch (Exception e) { e.printStackTrace(); } } } class Job { private String jobName; private Process process; private int terminatCode = 0; Job(String jobName) { this.jobName = jobName; terminatCode = 0; } void start() throws IOException { Runtime runtime = Runtime.getRuntime(); process = runtime.exec(jobName); } boolean isTerminated() { try { int terminatCode = process.exitValue(); } catch (IllegalThreadStateException e) { return false; } return true; } int getTerminatedCode() { return terminatCode; } void destroy() { process.destroy(); } }
このような方法jもあるよ 20090811_外部コマンドの実行
String str = "a" + "b" + "c";
このコードは、コンパイルされると
String str = new StringBuffer().append("a").append("b").append("c").toString();
となり、
StringBuffer buf = new StringBuffer(); buf.append("a"); buf.append("b"); buf.append("c"); String str = buf.toString();
と、効果は同じとなる。
単純な文字列連結であれば、StringBufferに置き換えなくても良いようだ。
参照 StringBuffer のjavadoc
import java.util.Date; import java.util.Properties; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; /* * 作成日: 2005/08/11 * 参考にしたURL * http://www.javadrive.jp/javamail/smtp/index1.html * http://www.atmarkit.co.jp/fjava/javatips/123java022.html * http://www.techscore.com/tech/J2EE/JavaMail/1.html * * このメソッドを起動するのに必要なjarは * mailapi.jar * activation.jar * smtp.jar * である */ public class Test { public static void main(String[] args) throws AddressException { Properties properties = new Properties(); properties.setProperty("mail.smtp.host", "mailgw.s-p.co.jp"); Session session = Session.getDefaultInstance(properties); MimeMessage mimeMessage = new MimeMessage(session); InternetAddress[] toAddress = { new InternetAddress("xxxx@xxxx.co.jp"), new InternetAddress("xxxx@xxxx.ne.jp"), }; try { // 宛先の設定 mimeMessage.setRecipients(MimeMessage.RecipientType.TO, toAddress); // 送信元の設定 mimeMessage.setFrom(new InternetAddress("xxxx@xxxx.ne.jp")); // サブジェクトの設定 mimeMessage.setSubject("pc started","iso-2022-jp"); // 本文の設定 mimeMessage.setText("pcが起動された","iso-2022-jp"); // 設定の保存(スグに送信する場合は不要) //mimeMessage.saveChanges(); //時刻の設定 mimeMessage.setSentDate(new Date()); // メールの送信 Transport.send(mimeMessage); } catch (MessagingException e) { e.printStackTrace(); return; } } }
起動方法
java -cp mailapi.jar;activation.jar;smtp.jar;. Test
int iii = 5; String sss = ""; DecimalFormat formatter = new DecimalFormat("000"); sss = formatter.format(iii); System.out.println(sss);
sss は 005 となります
よくネットに載っているは
Calendar systemCal = Calendar.getInstance(); Date systemDate = systemCal.getTime();
これでもできる
Date now = new Date();
//日付のフォーマッタを生成する SimpleDateFormat objFmt=new SimpleDateFormat("yyyy/MM/dd"); //日付型のデータを用意した(今回はシステム日付) Date now = new Date(); //フォーマットしてみる String stringDate = objFmt.format(now); //確認してみる System.out.println(stringDate);
http://www.atmarkit.co.jp/fjava/rensai2/jspservlet09/jspsevlet09_2.html
Integer型は、== 比較すると、インスタンスIDの比較になるので、値の比較をするときは、equalsメソッドか、intValueした値で比較する必要がある。
値の比較
Integer int1 = new Integer(1); Integer int2 = new Integer(1); System.out.println("== による比較"); if (int1 == int2){ System.out.println("同じ"); }else{ System.out.println("異なる"); } System.out.println("equals による比較"); if (int1.equals(int2)){ System.out.println("同じ"); }else{ System.out.println("異なる"); } System.out.println("intValue による比較"); if (int1.intValue() == int2.intValue()){ System.out.println("同じ"); }else{ System.out.println("異なる"); }
実行結果
== による比較 異なる equals による比較 同じ intValue による比較 同じ
ver1.5からの機能
例
System.out.printf("Sleeping begin %d Seconds",sleepSecond/1000);
sprintf に相当する
String.format("%d",i) で、String型を返却できる
ヒントになりそうな、URL
http://rainbowdevil.jp/mt/externalstorage/archives/2006/06/java_5.html
コンソールから デバッグ対象のモジュールを起動する
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
SleepExe 10
src/shodai/lesson/data.properties
key1=shodai.lesson.CC1 key2=value2
src\shodai\lesson\CC.java
package shodai.lesson; public abstract class CC { abstract void run(); }
src\shodai\lesson\CC1.java
package shodai.lesson; public class CC1 extends CC { @Override void run() { System.out.println("CC1"); } }
src\shodai\lesson\CC2.java
package shodai.lesson; public class CC2 extends CC { @Override void run() { System.out.println("CC2"); } }
src\shodai\lesson\Main.java
package shodai.lesson; import java.util.ResourceBundle; public class Main { public static void main(String[] args) { try { ResourceBundle bundle = ResourceBundle.getBundle("shodai.lesson.data"); String className = bundle.getString("key1"); CC cc = (CC)Class.forName(className).newInstance(); cc.run(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
実行結果
CC1
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class Main { /** * @param args */ public static void main(String[] args) { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:oracle:thin:@a50:1521:XE", "system", "???"); Statement stmt = con.createStatement(); String sql = "SELECT 'abc' str FROM dual"; ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { String str = rs.getString("str"); System.out.println(str); } stmt.close(); con.close(); } catch (Exception e) { e.printStackTrace(); } } }
JDBCドライバは、ものによって返る必要がある
オラクルのものを使う場合は、コレ
oracle.jdbc.driver.OracleDriver
パスワードは変更すること
JDBCはtype4を使用している。
type4は、JDBCドライバが直接、オラクルサーバーまで接続しにいくので、クライアントのインストールは不要である。
JDBCドライバが存在するだけでよい。
Eclipseの DB Viewも JDBCドライバだけで接続できる!
参照
../environment/environment.html#20090609_Oracle_JDBCドライバ_周りで_例外が発生
トランザクションを意識した実装をする場合は、以下のポイントを意識すること
トランザクションを使った更新の例
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class Main { public static void main(String[] args) { Connection con = null; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection("jdbc:oracle:thin:@a50:1521:XE", "userid", "password"); con.setAutoCommit(false); String sql = "update TEST_TBL1 set data_date = ? ,data_number = ? where key1 = ?"; PreparedStatement ps = con.prepareStatement(sql); ps.setObject(1, "2009/7/15"); ps.setObject(2, "123"); ps.setObject(3, 2); ps.executeUpdate(); ps.close(); con.commit(); } catch (SQLException e) { if (con!=null){ try { con.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } } catch (ClassNotFoundException e) { e.printStackTrace(); }finally{ if (con!=null){ try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
バインド変数を用いてみる
public class Main { public static void main(String args[]) throws ClassNotFoundException, SQLException { Class.forName("oracle.jdbc.driver.OracleDriver"); // Oracleに接続 con = DriverManager.getConnection("jdbc:oracle:thin:@a50:1521:XE", "userid", "password"); // ステートメントを作成 PreparedStatement stmt = conn.prepareStatement("select ID, NAME, BIRTHDAY from CUSTOMER WHERE ID=?"); stmt.setString(1, "00002"); // 問合せの実行 ResultSet rset = stmt.executeQuery(); // 問合せ結果の表示 while (rset.next()) { // 列番号による指定 System.out.println(rset.getInt("ID")); System.out.println(rset.getString("NAME")); System.out.println(rset.getDate("BIRTHDAY")); } // 結果セットをクローズ rset.close(); // ステートメントをクローズ stmt.close(); // 接続をクローズ conn.close(); } }
言語仕様には、無名パッケージがカレントフォルダに場合以外は使えない…とあった。
動作確認実装や、Mainクラス以外は、使用しないほうが無難
使い方
public final class ThreadLocalRegistry { private ThreadLocalRegistry() { } private static final ThreadLocal LOGININFORMATION = new ThreadLocal(); private static final ThreadLocal DATABASECONNECTION = new ThreadLocal(); public static synchronized void setLoginInformation( LoginInformation loginInformation) { ThreadLocalRegistry.LOGININFORMATION.set(loginInformation); } public static synchronized LoginInformation getLoginInformation() { return (LoginInformation) ThreadLocalRegistry.LOGININFORMATION.get(); } public static synchronized void setDataBaseConnection( DatabaseConnection databaseConnection) { ThreadLocalRegistry.DATABASECONNECTION.set(databaseConnection); } public static synchronized DatabaseConnection getDataBaseConnection() { return (DatabaseConnection) ThreadLocalRegistry.DATABASECONNECTION .get(); } }
改良の余地
synchronized はオブジェクトをロックするものである。staticメソッドにsynchronized をつけると、クラスをロックする。
個々のメンバーに関連が無いならば、個々のメンバーに対するsynchronizedブロックをつけたほうが良い。
アノテーションを構成する種類
使い方による分類
作成する観点からみた分類
http://itpro.nikkeibp.co.jp/article/COLUMN/20090115/322957/?ST=develop
http://www.ne.jp/asahi/hishidama/home/tech/java/reflection.html
http://wisdom.sakura.ne.jp/programming/java/java5_5.html
バインドするクラス
public class Field { public String name; public String value; }
import java.util.ArrayList; import java.util.HashMap; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class InputRecord { public String name; public HashMap<String, Field> fieldMap = new HashMap<String, Field>(); public ArrayList<Field> fieldList = new ArrayList<Field>(); }
マーシャル/アンマーシャルしてみる
import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; // http://d.hatena.ne.jp/cactusman/20090628/p1 public class Main { public static void main(String[] args) { //----テストインスタンスの生成-------------------------------- InputRecord inputRecord = new InputRecord(); inputRecord.name = "なまえ1"; Field field1 = new Field(); Field field2 = new Field(); Field field3 = new Field(); Field field4 = new Field(); field1.name = "フィールド名1"; field2.name = "フィールド名2"; field3.name = "フィールド名3"; field4.name = "フィールド名4"; field1.value = "001"; field2.value = "002"; field3.value = "003"; field4.value = "004"; inputRecord.fieldList.add(field1); inputRecord.fieldList.add(field2); inputRecord.fieldMap.put("map3",field3); inputRecord.fieldMap.put("map4",field4); //--------マーシャル処理 Java→XML ------------------------------ JAXBContext context = null; try { context = JAXBContext.newInstance(InputRecord.class); Marshaller marshaller = context.createMarshaller(); marshaller.marshal(inputRecord, new File("inputRecord.xml")); } catch (JAXBException e) { e.printStackTrace(); } InputRecord inputRecord2 = null; //--------アンマーシャル処理 XML→Java ------------------------------ try { context = JAXBContext.newInstance(InputRecord.class); Unmarshaller unmarshaller = context.createUnmarshaller(); inputRecord2 = (InputRecord) unmarshaller.unmarshal(new File("inputRecord.xml")); } catch (JAXBException e) { e.printStackTrace(); } System.out.println("end"); } }
inputRecord.xml の内容
参考
http://d.hatena.ne.jp/cactusman/20090628/p1
XMLに変換したとき、クラスのプロパティは、子ノードになる。
子ノードではなく、属性にしたいときは、javax.xml.bind.annotation.XmlAttribute を用いる。
プロパティ、または アクセサに @XmlAttribute をつける。 11/03
キーとして用いるクラスで、インスタンスIDが同じかどうかで、判定するなら良いが、クラス内部の実値で判定したい場合は、以下のようにせよ。
ポイント1
hashCode メソッド を オーバーライズして、実値が同じなら、同じ値を返すように実装せよ
ポイント2
equals メソッドをオーバーライズして、実値が同じなら、trueを返すように実装せよ
map のgetメソッドは、まずhashcodeで判定。hashcodeが同じ場合はequalsメソッドで判定している。
インスタンスIDが異なるとhashcodeが変わってくるので、内部フィールドのhashcodeの合計などとすると良い。
equalsは単純にするとインスタンスIDで比較してしまうので、それぞれのフィールドの値をequals比較する必要がある。
synchronized キーワードは、メソッド修飾子またはメソッド内のステートメントとして使用する。
synchronizedはオブジェクトをロックする。メソッド単位のロックではない。
static メソッド修飾子の場合は、メソッドが所属するクラスのオブジェクトがロックされる。
instanceメソッド修飾子の場合は、メソッドが所属するinstanceオブジェクトがロックされる。
class Test { public synchronized void method1() { // ... } public void method2() { synchronized (this) { // ... } } public void method3(SomeObject someObj) { synchronized (someObj) { // ... } } }
method1とmethod2は、ロックの意味合いは、まったく等価である。
Log4jについて考察してみた。詳しくはこちらで
シリアライズ→デシリアライズのサンプルソース
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InvalidClassException; import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OptionalDataException; import java.io.StreamCorruptedException; import data.Book; import data.SmallBook; /** * */ /** * クラスの説明。<BR> * * @author FIP Watanabe * */ // 2009/07/29 // http://book.geocities.jp/bits_of_java/java/io/serializable/sample2.html public class Main { public static void main(String[] args) { Book book = new SmallBook("きまぐれロボット","小さい"); // ------------------------------------------------ // シリアライズ // ------------------------------------------------ ObjectOutputStream out = null; try { out = new ObjectOutputStream(new BufferedOutputStream( new FileOutputStream("data.dat"))); // このメソッドでファイルに直列化 out.writeObject(book); out.flush(); } catch (InvalidClassException e) { // (java.io.ObjectStreamExceptionのサブクラス) // 直列化で使用されるクラスになんらかの不具合があった場合 System.out.println("直列化に失敗 - " + e); } catch (NotSerializableException e) { // (java.io.ObjectStreamExceptionのサブクラス) // 直列化の対象が java.io.Serializableを実装していない場合 System.out.println("直列化に失敗 - " + e); } catch (IOException e) { // 基本となる OutputStream が例外をスローした場合 System.out.println("直列化に失敗 - " + e); } finally { if (out != null) { try { out.close(); } catch (IOException e) { } } } // ------------------------------------------------ // デシリアライズ // ------------------------------------------------ Book book2 = null; ObjectInputStream in = null; try { in = new ObjectInputStream(new BufferedInputStream( new FileInputStream("data.dat"))); //このメソッドでファイル(とロードされているクラス)から復元 book2 = (SmallBook)in.readObject(); System.out.println(book); } catch (InvalidClassException e) { //(java.io.ObjectStreamExceptionのサブクラス) //クラスの直列化バージョンが、ストリームから読み込まれた //クラス記述子の直列化バージョンと一致しない場合 //クラスに未知のデータ型が含まれている場合 //クラスに、アクセス可能な引数なしのコンストラクタがない場合 System.out.println( "復元に失敗 - " + e); } catch (StreamCorruptedException e) { //(java.io.ObjectStreamExceptionのサブクラス) //オブジェクトストリームから読み込まれた制御情報が、 //内部整合性検査に違反していた場合にスローされます。 System.out.println( "復元に失敗 - " + e); } catch (OptionalDataException e) { //(java.io.ObjectStreamExceptionのサブクラス) //プリミティブデータが読み込まれていないか、 //またはデータの終わりがストリーム内の直列化オブジェクトに //あるため、オブジェクトの読み込み操作が失敗したことを示す例外 System.out.println( "復元に失敗 - " + e); } catch (IOException e) { //入出力に関連した例外 System.out.println( "復元に失敗 - " + e); } catch (ClassNotFoundException e) { //直列化されたオブジェクトのクラスが見つからなかった場合 System.out.println( "復元に失敗 - " + e); } finally { if (in != null) { try { in.close(); } catch (IOException e) {} } } System.out.println(book2); } }
Mapの内部のデータを、Key順にソートしたい時の話。
方法1
TreeMap クラスを用いる方法。TreeMapは、データをputした時に、すぐにソートされる。便利だが、putのコストがかかると思われる。
方法2
HashMapにデータを登録しておく。TreeMapを、Newするときに、Mapを引数にとる事ができる。Nnewされたときには、ソートされた状態になっている
使用頻度が高そうなメソッドを集めてみた
/** * 引数で指定されたリストに対し、重複した要素を除去します。<br> * @param list ユニーク化する対象のリスト */ static public <T extends List<E>, E> void unique(T list) { //LinkedHashSetが重複した要素をもてない事を利用しています HashSet<E> set = new LinkedHashSet<E>(list); list.clear(); list.addAll(set); }
exeタイプの場合
import java.io.IOException; public class MainPGの実行 { public static void main(String[] args) { String sss = "notepad.exe"; Process process = null; try { process = Runtime.getRuntime().exec(sss); } catch (IOException e1) { e1.printStackTrace(); return; } try { //終了するまで待ち合わせ process.waitFor(); } catch (Exception e2) { System.out.println("interrupted!!!"); } } }
dirなどのコマンドは exec 引数に直接入れても起動されない。
String[] cmdarray = {"command.com", "/c", "dir"};
runtime.exec(cmdarray);
のようにします。さらにコマンドの戻り値も取得してみましょう
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class MainOSコマンド { public static void main(String[] args) { Process process = null; String cmd = "cmd /c dir c:\\" ; try { process = Runtime.getRuntime().exec(cmd); } catch (IOException e1) { e1.printStackTrace(); return; } String[] returns = new String[3]; /* * 配列[0] ⇒ 標準出力 * 配列[1] ⇒ エラー出力 * 配列[2] ⇒ リターンコード */ String LINE_SEPA = System.getProperty("line.separator"); InputStream in = null; BufferedReader br = null; try { in = process.getInputStream(); StringBuffer out = new StringBuffer(); br = new BufferedReader(new InputStreamReader(in)); String line; while ((line = br.readLine()) != null) { out.append(line + LINE_SEPA); } returns[0] = out.toString(); in = process.getErrorStream(); StringBuffer err = new StringBuffer(); br = new BufferedReader(new InputStreamReader(in)); while ((line = br.readLine()) != null) { err.append(line + LINE_SEPA); } returns[1] = err.toString(); returns[2] = Integer.toString(process.waitFor()); } catch (InterruptedException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) { br.close(); } if (in != null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } System.out.println(returns[0]); System.out.println(returns[1]); System.out.println(returns[2]); } }
今回の原因は、他の場所でこのばあい、 <割当サイズ>13</サイズ゙> という へんな名前がついていたからだった。
行番号、列番号 とは、異なる恐れがあるので、注意
../../oracle_global/oracle_global.html#20100227_DATE型から時分秒が取得できないとき
StringBuilder | StringBuffer |
JDK 1.5 | JDK 1.0 |
スレッドアンセーフ | スレッドセーフ |
割と高速らしい | 高速ではないらしい |
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/StringBuffer.html
文字の可変シーケンスです。このクラスは、StringBuffer
と互換性がある API
を提供しますが、同期化は保証されません。このクラスは、文字列バッファが単一のスレッド (一般的なケース) により使用されていた場合の
StringBuffer
の簡単な代替として使用されるよう設計されています。このクラスは、ほとんどの実装で高速に実行されるので、可能な場合は、StringBuffer
よりも優先して使用することをお勧めします。
列挙型とも言われる。
public class EnumTest { enum Suit {CLUBS, DIAMONDS, HEARTS, SPADES} public static void main(String[] args) { Suit suit = Suit.CLUBS; System.out.println("Suit is " + suit); } }
参考
http://www.javainthebox.net/laboratory/J2SE1.5/LangSpec/TypesafeEnum/TypesafeEnum.html