Javaの文法はJavaプログラムを記述し解釈する方法を定義するルールの集合である。
目次 |
Javaは配列と文字列を扱うため専用の文法を持ってはいるが、配列と文字列は基本型ではない: それらはjava.lang.Objectに代入できる参照型である。
| 整数型 | |
|---|---|
| byte | 8-bit 符号付き |
| short | 16-bit 符号付き |
| int | 32-bit 符号付き |
| long | 64-bit 符号付き |
| 浮動小数点数型 | |
|---|---|
| float | 32-bit 符号付き |
| double | 64-bit 符号付き |
| 文字 | |
|---|---|
| char | 16-bit 符号無しUnicode |
| ブール型 | |
|---|---|
| boolean | true または false |
| 整数 | |
|---|---|
| 8進数 | 0365, 0[0..7]* |
| 16進数 | 0xF5, 0x[0..9, A..F, a..f]* |
| 10進数 | 245, [1..9][0..9]* |
| 浮動小数点数型 | |
| float | 23.5F, 23.5f; 1.72E3F, 1.72E3f, 1.72e3F, 1.72e3f |
| double | 23.5, 23.5D, 23.5d; 1.72E3, 1.72E3D, ... |
| 文字リテラル | |
| char | 'a', 'Z', '\u0231' |
| 文字列リテラル | |
| String | "Hello, world" |
| エスケープシーケンス | |
| Unicode文字 | \u 16進数Unicode文字を表現するときに使用する |
| タブ文字 | \t |
| 後退(Backspace)文字 | \b |
| キャリッジリターン(復帰文字) | \r |
| 改ページ | \f |
| バックスラッシュ | \\ |
| シングルクォーテーション(単一引用符) | \' |
| ダブルクォーテーション(二重引用符) | \" |
| ラインフィード(改行文字) | \n |
文字列
Stringオブジェクトは不変(変更不能)である<source lang="java"> String str1 = "alpha"; String str2 = new String("alpha"); </source>
StringBufferとStringBuilderオブジェクトは可変(変更可能)なので、オブジェクト生成オーバヘッド無しで柔軟に文字列を生成・変更出来る。StringBufferとStringBuilderの違いは、StringBufferがマルチスレッドに対応している(=スレッド・セーフである)のに対し、StringBuilderは対応していないことである。<source lang="java"> StringBuffer str1 = new StringBuffer("alpha"); str1.append("-meta"); str1.setCharAt(str1.indexOf("m"), 'b'); System.out.println(str1); //str1.toString() を呼び出す。
//印刷結果は"alpha-beta"となる
</source>
java.lang.Objectを引き継ぎ、そこに含まれる型階層を反映する。length」を持つ。// 配列を宣言 - 配列名は「myArray」、 要 の型は "SomeClass" への参照 SomeClass[] myArray = null;
// 配列を生成 myArray = new SomeClass[10];
// または宣言と生成を同時に行う SomeClass[] myArray = new SomeClass[10];
// 配列の要 を割り当てる (但し、基本型の配列なら必要ない)
for (int i = 0; i < myArray.length; i++)
myArray[i] = new SomeClass();
Java言語はbyteと文字型とを区別する。文字は内部的にはUCS-2で表現されるが、J2SE 5.0以降においては、内部表現としてUTF-16とそのサロゲートもサポートされる。従ってJavaプログラムのソースには、あらゆるUnicode文字を記述出来る。
ゆえに、次の例はJavaのコードとして完璧に有効である。ここではクラス名、変数名、及び文字列リテラルとして日本語の文字を使っている:
public class こんにちは世界 {
private String 文字列 = "こんにちは世界";
}
| 二項演算子 | |
|---|---|
| 文法 | 意味 |
| + | 加算 |
| - | 減算 |
| * | 乗算 |
| / | 除算 |
| % | 剰余 (整数の余りを返す) |
| 単項演算子 | |
| 文法 | 意味 |
| - | 単項マイナス (符号反転) |
| ++ | インクリメント (変数の前か後につけることができる) |
| -- | デクリメント (変数の前か後につけることができる) |
| ! | ブール補数演算 |
| ~ | ビット単位反転 |
| (型名) | キャスト |
| 文法 | 意味 |
|---|---|
| = | 代入 |
| += | 加算と代入 |
| -= | 減算と代入 |
| *= | 乗算と代入 |
| /= | 除算と代入 |
| %= | 剰余と代入 |
| &= | ビット演算 ANDと代入 |
| |= | ビット演算 ORと代入 |
| ^= | ビット演算 XORと代入 |
| <<= | 左シフト(ゼロ埋め)と代入 |
| >>= | 右シフト (符号拡張)と代入 |
| >>>= | 右シフト (ゼロ埋め) と代入 |
| 文法 | 意味 |
|---|---|
| == | = |
| != | ≠ |
| > | > |
| >= | ≧ |
| < | < |
| <= | ≦ |
| instanceof | ~のインスタンス |
関係演算子(==と!=)を参照型に対して用いた場合、そこで比較されるのは参照先のオブジェクトが同じかどうかであり、オブジェクトの中身の値が一致するか否かではない。オブジェクトの中身を比較したい場合は.equals(Object)メソッドを使用する。instanceof演算子は或るオブジェクトが或るクラスのインスタンスであるか否かを判定するために用いる。
三項演算子は二つの記号?と:を組み合わせて記述する。条件演算子とも呼ぶ。構文:
条件 ? 式1 : 式2
条件がtrueであるとき、式1の値をとる。そうでない場合は式2の値をとる。
例:
<source lang="java"> String answer = (p < 0.05)? "reject": "keep"; </source>
<source lang="java"> // これは以下のコードと等価である: String answer; if (p < 0.05){
answer = "reject";
}else{
answer = "keep";
} </source>
| 文法 | 意味 |
|---|---|
| && | AND (左のオペランドがfalseのとき、式はfalseを返し、右のオペランドは評価されない) |
| || | OR (左のオペランドがtrueのとき、式はtrueを返し、右のオペランドは評価されない) |
| ! | NOT (論理否定) |
(訳注: 上の通り、&&と||は左のオペランドしか評価しない可能性がある。これに対し、ビット演算子にも挙げられている&と|を代わりに書いた場合は、左右のオペランド両方が完全に評価される。実用上は&&と||を用いるのが一般的である)
| 二項演算子 | |
|---|---|
| & | AND (論理演算子としても使用可。その場合両辺が完全に評価される) |
| | | OR (論理演算子としても使用可。その場合両辺が完全に評価される) |
| ^ | XOR |
| << | 左シフト (ゼロ埋め) |
| >> | 右シフト (符号拡張) |
| >>> | 右シフト (ゼロ埋め) |
| 単項演算子 | |
| ~ | NOT (ビット反転) |
| Syntax | Meaning |
|---|---|
| + | 連結 |
| += | 連結と代入 |
if (expr) {
statements;
}
else if (expr) {
statements;
}
else {
statements;
}
(訳注: この部分は原文も意味が取り辛く不適切な記述と思われる。ここで言わんとしているのは「関係演算子」の節で述べている事柄であろう。)
switch (expr) {
case VALUE:
statements;
break;
case VALUE:
statements;
break;
default:
statements;
break;
}
for (initial-expr; cond-expr; incr-expr) {
statements;
}
J2SE 5.0では、for-each文と呼ばれる新機能が追加された。これは集合の中の全要素を順番に参照するような処理を大いに簡素化する。このような場合、従来は次の例に示すような反復子(iterator)を書かねばならなかった: <source lang="java"> public int sumLength(Set<String> stringSet) {
int sum = 0;
Iterator<String> itr = stringSet.iterator();
while (itr.hasNext()) {
sum += itr.next().length();
}
return sum;
} </source>
for-each文はこのメソッドを大いに簡素化する:
<source lang="java"> public int sumLength(Set<String> stringSet) {
int sum = 0;
for (String s : stringSet) {
sum += s.length();
}
return sum;
} </source> この例の動作としては、stringSetに含まれる全てのStringについて、長さを取得してsumに加算する。
while (expr) {
statements;
}
do {
statements;
} while (expr);
| 文法 | 意味 |
|---|---|
| break; | 最も深いループから直ちに脱出する。 |
| continue; | ループの現在の回を中断し、次の回の冒頭に移る。 |
| break LABEL | ラベル付き文の実行を中断し、ラベル付き文の直後の文に移る。 |
| continue LABEL | ラベル付きの文にジャンプする(ラベル付きの文またはラベル付きループを冒頭から再開する) |
<source lang="java"> int sum = 0; for (int i = 1; i < 10; i++) {
if (i == 3) {
continue; //このループの残りをスキップしforに戻る。
}
sum += i;
if (sum > 15) {
break; // ループを脱出する。
}
} </source> (訳注:原文のサンプルのバグを修正した。)
例
LABEL1: statement;
LABEL2: { statements; }
"goto" 文はJavaの予約語であるが、Javaでは機能しない。
Javaでは別のクラスやインタフェース内部で宣言された「ネスト」されたクラスを作ることが出来る。ネストされていないクラスは「トップレベル」クラスと呼ばれる。非staticなネストされたクラスのことは「内部クラス」と呼ぶ。
クラスを宣言する際は以下の修飾子を付けることが出来る:
abstract(抽象)クラスだけがabstract(抽象)メソッドを持つことができる。抽象クラスを継承する具象(非abstract)サブクラスは、引き継がれた全ての抽象メソッドを、abstractでないメソッドでオーバーライドしなければならない。修飾子finalと併用することはできない。Javaのクラスはセミコロン(";")で終わらせる必要は無い点に注意。この点はC++の文法と異なる。
// 子クラスは親クラスを継承する
class ChildClass extends ParentClass { ... }
Objectクラスである。this.someMethod())。super.someMethod())。サブクラスがオーバライドした親クラスのメソッドや、サブクラスが継承しつつも隠蔽した親クラスのフィールドにアクセスするために使うことが出来る。インタフェースとは、実装の詳細が一切無い抽象クラスである。その目的は複数のクラスの用途をまとめて定義することにある。共通のインタフェースを実装する複数のクラスは、そのインタフェース型のコンテキストに従って互いに交換可能とすることができる。インタフェースはまた、抽象化 クラスの実装方法を隠蔽すること という考え方を強制するのにも役立つ。
インタフェースは抽象メソッドとstatic finalフィールドだけを含むことができる。インタフェースメソッドはデフォルトでpublicかつabstractであり(実装を持たない)、インタフェースフィールドはデフォルトで public static final である。
Javaは完全な直交の多重継承はサポートしていない。C++における多重継承には、複数の親クラスや型から複数回継承したフィールドやメソッドを識別するための複雑なルールが伴う。インタフェースを実装から分離することにより、インタフェースはより単純かつ明快に多重継承が持つ利点の多くを提供する。尤も、多重継承を避ける代価としてコードは若干冗長になる。というのは、インタフェースはクラスのシグネチャを定義するのみで実装を持てないため、インタフェースを継承する全てのクラスは定義されたメソッドをいちいち実装しなければならないからである。純粋な多重継承であれば実装自体も継承されるのでこのようなことはない。
Javaのインタフェースは Objective-C規約のコンセプトによく似た振る舞いをする。
クラスは、一つのクラスを継承できるのに加えて、implementsキーワードを用いて一つ以上のインタフェースを実装することができる。
interface MyInterface {
void foo();
}
interface Interface2 {
void bar();
}
class MyClass implements MyInterface {
void foo() {...}
...
}
class ChildClass extends ParentClass implements MyInterface, Interface2 {
void foo() {...}
void bar();
...
}
以下の例では、
public interface Deleteable {
void delete();
}
Deleteableインタフェースを実装する非abstractクラスは、引数無しで戻り型がvoidであるdeleteという名前の非抽象メソッドを定義しなければならない。そのメソッドの実装と機能は各々のクラスによって決定される。このコンセプトには様々な使い道がある。例えば:
public class Fred implements Deleteable {
// このメソッドはDeleteableインタフェースを満足する
public void delete() {
// ここにコードを実装
}
public void someOtherMethod() {
}
}
public void deleteAll(Deleteable[] list) {
for (int i = 0; i < list.length; i++) {
list[i].delete();
}
}
上の配列に含まれる全てのオブジェクトはdelete()メソッドを持つことが保証されるので、deleteAll()メソッドはFredオブジェクトと他の如何なるDeleteableオブジェクトをも区別する必要がない。
インタフェースはextendsキーワードを用いて一つ以上のインタフェースを継承することができる。
interface ChildInterface extends ParentInterface, AnotherInterface {
...
}
結果として生じるインタフェースを実装するクラスは、元のインタフェースに含まれたメソッドをも併せて定義しなければならない。
public interface MyInterface {
foo();
}
public interface Interface2 extends MyInterface {
bar();
}
public class MyClass implements Interface2 {
void foo() {...}
void bar() {...}
...
}
アクセス修飾子は、そのクラスやクラスメンバにアクセス可能なコードが誰であるかを決定する。
デフォルトでは、Javaのクラスは、それら自身のJavaパッケージからのみアクセスできる。これは、クラスのパッケージが、裏に隠れて機能を実行するようなAPIを提供することを可能とする。外にアクセスを公開されたクラスの動作を、隠されたクラスが支える形になる。
クラスメンバとはフィールド、メソッド、コンストラクタ、クラス内で定義されたネストされたクラスのことである。アクセス制限が厳しいものから並べると、クラスメンバのアクセス修飾子は次の通り。
private宣言されたメンバはサブクラスによって引き継ぐことができない。メソッドをオーバライドする際、そのメソッドのアクセス権を「より厳しく」することはできない。さもなくば親クラスのインタフェース契約を壊してしまうからである。従ってオーバライドされる場合、publicメソッドはpublicとして宣言されねばならず、protectedメソッドをデフォルトアクセス権(修飾子省略)とすることは出来ない。しかしながら、メソッドをオーバライドしてアクセス権を「より緩める」ことは許される。従ってオーバライドする際、デフォルト(パッケージ)アクセス権のメソッドはprotectedまたはpublicとして宣言することができ、protectedメソッドはpublicとして宣言することができる。
アクセス修飾子に加えて、データフィールドは以下の修飾子によって宣言される:
staticなブランクfinalフィールドは最終的にスタティックイニシャライザによって初期化されなければならない。staticでないブランクfinalフィールドはコンストラクタの実行中に必ず初期化されなければならない。volatileにはなれない。staticとfinal両方を宣言されたフィールドは事実上、定数である。staticはそのフィールドがそのクラスにおいてただ一つのみ存在することを示し、finalはそのフィールドがただ一度のみ値を設定(初期化)可能であることを意味する。
「イニシャライザ」(初期化子)はフィールドのイニシャライザと同時に実行されるコードのブロックである。
「スタティックイニシャライザ」(静的初期化子)はstaticフィールドのイニシャライザと同時に実行されるコードのブロックである。静的フィールド初期化子と静的初期化子は宣言された順番に実行される。静的初期化はクラスがロードされた後で実行される。
<source lang="java"> static int count = 20; static int[] squares; static { // スタティックイニシャライザ
squares = new int[count];
for (int i = 0; i < count; i++)
squares[i] = i * i;
} static int x = squares[5]; // x には値25が代入される。 </source>
「インスタンスイニシャライザ」(インスタンス初期化子)はインスタンスの(非staticな)フィールドの初期化子と同時に実行されるコードのブロックである。インスタンスフィールド初期化子とインスタンス初期化子は宣言された順番に実行される。
インスタンス初期化子とインスタンスフィールド初期化子はコンストラクタが呼び出された際に実行される。正確な実行順序としては、親クラスのコンストラクタが実行された後、かつ、自身のコンストラクタが実行される前、となる。
アクセス修飾子に加えて、メソッドには以下の修飾子を付けて宣言できる:
abstract)サブクラスによって定義されなければならない。static、final、nativeの何れとも併用できない。static) メソッドでありかつ十分小さいならば、コンパイラはそのメソッドをインライン関数のように各所に展開する場合がある(訳注:性能改善目的と思われる)。abstractと併用はできない。Classオブジェクトを指し、非staticならばオブジェクトインスタンスを指す。abstractメソッドをsynchronizedとして宣言することは可能だが意味はない。何故なら排他とは宣言ではなく実装に伴う機能であり、抽象メソッドは実装を持たないからである。privateメソッドは自ずからfinalであり、abstractには出来ない点に注意。
Java SE 5.0において、引数の個数が可変であるようなメソッドについての文法上の便宜(varargs)[1]が追加された。これによって引数の個数が可変であるメソッドをタイプセーフに使用することが容易になる。最後のパラメタの後に「...」と書くと、Javaは全ての引数を配列に格納する:
public void drawPolygon (Point... points) {…}
このメソッドを呼ぶ際、プログラマは個々のpointsを単にカンマで区切って書けばよく、Pointオブジェクトの配列をわざわざ用意する必要はない。このメソッドの内部でpointsを参照する際はpoints[0]、points[1]、などのように書ける。pointsが渡されていない場合、配列のlengthは0となる。可変個の引数と別に固定的に必要なパラメタがある場合は、それらのパラメタは可変引数に先立って指定すればよい。
<source lang="java"> // ポリゴンは少なくとも3つの点を必要とする。 public void drawPolygon (Point p1, Point p2, Point p3, Point... otherPoints) {…} </source>
コンストラクタはオブジェクトが割り当てられた後すぐに呼び出され、オブジェクトの初期処理を行う。コンストラクタは典型的にはnewキーワードを使用して呼び出されるが、リフレクションを使用して呼ぶことも出来る。リフレクション機能はjava.lang.reflectパッケージより提供される。
コンストラクタを宣言する際に使える修飾子はアクセス修飾子のみである。
super(...);または同じクラス内の別のコンストラクタ:this(...);を呼び出せる。super(...) または this(...)に対する明示的な呼び出しが無いならば、コンストラクタ本体が実行される前に、親クラスのデフォルトコンストラクタsuper();が呼ばれる。ObjectクラスのメソッドObjectクラスのメソッドは継承されるので、全てのクラスにて使用できる。
cloneメソッド詳細はクローン (関数)を参照
Object.clone()メソッドは現在のオブジェクトのコピーである新しいオブジェクトを返す。クラスは、それがクローンできることを明示するためにマーカーインタフェースCloneableを実装しなければならない。
equalsメソッドObject.equals(Object)メソッドはそのオブジェクトともう一つのオブジェクトを比較し、二つのオブジェクトが同一かどうかをboolean型の値で返す。意味的には、このメソッドはオブジェクトの内容を比較するのに対し、関係演算子"=="はオブジェクトの参照を比較する。equalsメソッドはjava.utilパッケージにあるデータ構造クラスの多くで使われる。これらのデータ構造クラスのいくつかはObject.hashCodeメソッドにも依存している - equalsとhashCodeとの間の契約の詳細について、hashCodeメソッドを参照のこと。
finalizeメソッド詳細はファイナライザを参照
Object.finalize()メソッドはガーベッジコレクタがオブジェクトのメモリを解放する前に必ず一度だけ呼び出される。オブジェクトが消滅する前に実行しなければならない何らかの後処理がある場合、各クラスはfinalizeをオーバーライドすることが出来る。とはいえ殆どのオブジェクトはfinalizeをわざわざオーバーライドする必要はない。
finalizeメソッドがいつ呼ばれるかは保証されない。複数のオブジェクトのfinalizeがどのような順番で呼ばれるかも不定である。もしJVMがガーベッジコレクションを実行せずに終了するならば、OSがオブジェクトを解放する可能性があり、その場合finalizeメソッドは呼ばれない。
finalizeメソッドは、他のクラスから呼ばれるのを防ぐために、常にprotectedとして宣言されるべきである。
protected void finalize() throws Throwable { ... }
getClassメソッドObject.getClass()メソッドはオブジェクトをインスタンス化するために使われたクラスのClassオブジェクトを返す。このクラスオブジェクトはJavaにおけるリフレクションの基本となる。その他のリフレクション機能はjava.lang.reflectパッケージにて提供される。
hashCodeメソッドObject.hashCode()メソッドは連想配列にオブジェクトを保存するための「ハッシュ値」として(int型の)整数を返す。java.util.Mapインタフェースを実装するクラスは連想配列を提供しhashCodeメソッドに依存する。hashCodeの良い実装は安定(不変)かつ均等に分布するハッシュ値を返す(異なるオブジェクトのハッシュ値は互いに異なる値となる傾向を持ち、かつハッシュ値は整数値の範囲内で均等に分布する。)。
連想配列はequalsとhashCodeの両メソッドに依存するため、これら二つのメソッドの間では、オブジェクトがMapに挿入される場合に関する或る重要な契約[1]が維持されねばならない:
a.equals(b) == b.equals(a)でなければならない。a.equals(b)ならばa.hashCode() == b.hashCode()でなければならない。この契約を維持するために、equalsメソッドをオーバーライドしたクラスは同時にhashCodeメソッドもオーバーライドし、逆もまた同様として、hashCodeとequalsが常に同じ性質(または同じ性質の一部)に基づくようにしなければならない。
マップがオブジェクトとの間に有する更なる契約は、ひとたびオブジェクトがマップに挿入されたなら、hashCode と equals両メソッドの結果は以後変わらないということである。従って、一般にハッシュ関数はオブジェクトの不変(変更不能)な属性に基くように設計するのが良い。
toStringメソッドObject.toString()メソッドはオブジェクトの文字列表現をStringで返すものである。toStringメソッドは、オブジェクトが文字列連結演算子(+と+=)のオペランドとして使われたとき、コンパイラによって暗黙のうちに呼び出される。
全てのオブジェクトは、そのオブジェクトに関連するスレッドについての二つの待ちリストを持つ。一つの待ちリストはsynchronizedキーワードに伴いオブジェクトをミューテックス排他するために使われる。もしミューテックスが他スレッドによって排他されているならば、自スレッドは排他を待っているスレッドのリストに追加される。もう一つの待ちリストはスレッド間でシグナルを送るためのもので、これはwait、notify、notifyAllの各メソッドを通して使用される。
wait/notifyを用いるとスレッド間での能率的な連携が可能となる。あるスレッドが別スレッドでの処理が終わるのを待ち合わせる必要があるとき、または何らかのイベントが発生するまで待たねばならないとき、スレッドはその実行を一時停止してイベントが発生した際に通知を受け取ることが出来る。これはポーリングとは対照的である。ポーリングにおいては、スレッドは一定時間スリープしてはフラグや他の状態表示をチェックする処理を繰り返す。ポーリングはスレッドがチェックを繰り返さねばならないという点でより計算コストが掛かる上に、実際にチェックしてみるまでイベント発生を検知できないという意味で鈍感でもある。
waitメソッドwaitメソッドには三つのオーバーロード版があり、タイムアウト値の指定方法がそれぞれ異なる:wait()、wait(long timeout)、wait(long timeout, int nanos)の三つである。一つ目のメソッドはタイムアウト値が0であり、これはタイムアウトが発生しないことを意味する。二つ目のメソッドはミリ秒単位のタイムアウト値を取る。三つ目のメソッドはナノ秒単位のタイムアウト値を取り、これは1000000 * timeout + nanosとして計算される。
waitを呼んだスレッドは待機状態となり、そのオブジェクトの待ちリストに追加される。そのスレッドは以下の三つのイベントの何れか一つが起きるまで、オブジェクトの待ちリスト上に留まる:
notifyまたはnotifyAllメソッドを呼ぶ (詳細はnotifyメソッド参照)interrupt()メソッドを呼ぶwaitにて指定した0でないタイムアウト値が満了するwaitメソッドは、そのオブジェクトについての同期(synchronized)ブロックまたは同期(synchronized)メソッドの内部からのみ呼ばねばならない。これはwaitとnotifyとの間で競合を起こさないためである。スレッドが待ちリストに入るとき、そのスレッドはそのオブジェクトのミューテックス排他を解除する[2]。そのスレッドが待ちリストから削除され実行可能スレッドとなった際に、そのスレッドは走行を再開するのに先立ってそのオブジェクトのミューテックスを改めて排他しなければならない。
notifyとnotifyAllメソッドObject.notify() と Object.notifyAll() メソッドはオブジェクトの待ちリストから一つ以上のスレッドを削除し、それらを実行可能スレッドとする。notifyは待ちリストから1スレッドのみ削除し、notifyAllは待ちリストから全てのスレッドを削除する。notifyがどのスレッドをリストから削除するかは規定されておらず、JVMの実装に依存する。
notifyとnotifyAllメソッドは、そのオブジェクトについての同期(synchronized)ブロックまたは同期(synchronized)メソッドの内部からのみ呼ばねばならない。これはwaitとnotifyとの間で競合を起こさないためである。
J2SE1.4よりも前のバージョンのJavaはストリーム・ベースのブロッキングI/Oのみをサポートしていた。これは1ストリームにつき1スレッドを必要とした。何故ならストリームの入力または出力を行おうとすると、それが完了するまでそのスレッドは完全に待ちに入ってしまい、他の処理が一切行えなくなったからである。これは、Javaを用いたネットワークサービスを構築する上で、スケーラビリティと性能双方の面で大きな問題となっていた。J2SE1.4以降では非ブロッキングI/OフレームワークとしてNIO(New I/O)が導入され、このスケーラビリティ問題は修正された(但し、サンによるNIO APIの実装にはまだ多くの問題点がある)。
非ブロッキングIOフレームワークは、以前のブロッキングIOフレームワークより遥かに複雑ではあるが、一つのスレッドで任意の数の"チャネル"を扱うことができる。このフレームワークはReactorパターンをベースとしている。
public class MyClass {
public static void main (String[] args) {...}
...
}
詳細はJavaアプレットを参照
// MyApplet.java
import java.applet.*;
public class MyApplet extends Applet {
init() {...} // ブラウザが最初にアプレットを読み込むときに呼ばれる。
destroy() {...} // ユーザがブラウザを終了するときに呼ばれる。
start(){...} // アプレットを実行し始めるときに呼ばれる。
stop() {...} // ユーザがウェブページを去るとき、再読込するとき、
// ブラウザを終了するときに呼ばれる。
}
<applet code="MyApplet" width="200" height="200">
</applet>
// MyApplet.java ... /* <applet code="MyApplet" width="200" height="200"> </applet> */ ...
詳細はJava Servletを参照
詳細はJavaServer Pagesを参照
| 文法 | 意味 |
|---|---|
| <% Java構文%> | スクリプトレット |
| <%= 単一Java構文の出力%> | 構文 |
| <%! Java宣言文%> | 宣言 |
| <%@ [page, include, taglib] JSPディレクティブ%> | ディレクティブ |
Javaはケースセンシティブ (大文字小文字を区別する) である。
// 一行コメント
/* 複数行 コメント */
/** * この行はクラス、インタフェース、メソッド、データメンバ宣言の直前に記述する。 * このコメントはクラスのドキュメンテーションを自動生成する * ユーティリティで使用することができる。 */
|
|
|
|---|---|
| 主要技術 | プログラミング言語Java - Javaプラットフォーム - Java Development Kit - Java仮想マシン - Java Runtime Environment - Javaコンパイラ - Javaバイトコード - JAR |
| 歴史 | Javaに対する批判 - Java Community Process - サン・マイクロシステムズ |
| 言語機能 | 文法 - Javaの予約語 - パッケージ - Javadoc |
| 関連技術 | Jakarta Project - Apache Tomcat - NetBeans - Java Beans - Java Message Service - Java Transaction API - Java3D - JDBC - Java Web Start - Applet - Servlet - JavaServer Pages - Java Foundation Classes |