この記事は、Java に精通した開発者の方に、ActionScript 3.0 (以下 AS3) がどのような言語なのか、どこが Java と異なっているのか (あるいは同じなのか) を一覧できるようまとめたものです。主に AS3 の静的な側面をまとめた、文法編 (文法編) およびクラス宣言編 (クラス宣言編)と、動的な側面をまとめた、属性操作編 (属性操作編) および振舞い編 (振舞い編) の 4 編に分けて、Java 開発者が引っかかりやすいと思われる点を中心に記述しました。厳密な言語解説よりは、まず AS3 の概要が分かること、を目的に書かれています。さらに詳しい言語仕様についてはActionScript 3.0 の学習をご覧ください。
文法編の内容
文法編では、要素と宣言に関わる基本的な文法を扱います。とはいっても、Java と AS3 の文法はいろいろな面で似ています。そのため、この記事では、特に違いを意識する必要がありそうな項目に絞って説明します。
下は、Java と AS3 それぞれのクラス宣言の例です。ひとめでは、どちらのサンプルか分からない程度に似ています。
package foo; import foopack.*; public class Foo extends FooBase implements IFoo { private String str = "文字列"; public int bar(boolean b) { return 0; } }
package foo { import foopack.*; public class Foo extends FooBase implements IFoo { private var str:String = "文字列"; public function bar(b:Boolean):int { return 0; } } }
要素/文法
セミコロン(;)
Java は文末にセミコロンが必要です。
foo = 0;
AS3 はセミコロンが必須ではありません。一行に複数の文を書く場合は、セミコロンで区切ります。
foo = 0 bar = 1; baz = 2
文法上は不要でも、可読性のため、セミコロンを付けることが推奨です。
null, undefined, NaN,
Java では初期化されていないオブジェクトの値は null です。
Object foo; Number num; System.out.println(foo); // 'null' が出力される System.out.println(num); // 'null' が出力される
AS3 はオブジェクトの型により "null", "undefined", "NaN" と値が変わります。
var foo; var bar:Object; var baz:*; var num:Number; trace(foo); // 'undefined' が出力される trace(bar); // 'null' が出力される trace(baz); // 'undefined' が出力される trace(num); // 'NaN' が出力される
型注釈の無い場合のみ、値が undefined になります。変数の型注釈に * 記号を指定すると、型注釈を使用しない場合と同じ扱いになります。その他、変数のデフォルト値については、アドビのヘルプ内のデフォルト値一覧をご覧ください。
プリミティブ型
Java には 8 つのプリミティブ型があります。例えば int はプリミティブ型です。int をオブジェクトとして使用したい場合はラッパークラスである Integer を使います。
int i = 123; Integer n = new Integer(i); n.toString();
AS3 ではプリミティブ型もオブジェクトです。そのため int 型の変数に対してもメソッドを呼び出すことができます。当然ラッパークラスは存在しません。
var i:int = 123; i.toString();
AS3 のプリミティブ型に関する詳細は、アドビヘルプのデータ型のまとめをご覧ください。
キャスト
Java のキャストは、変数の前に括弧付きで型を指定します。
float f = 5.0; int i = (int)f; // i は 5
AS3 のキャストは関数呼び出しと同じ形式です。詳細はアドビヘルプの型変換の節に詳しく書かれています。
var f:Number = 5.0; var i:int = int(f); // i は 5
AS3 では、データ型の検査に as 演算子を使うことができます。
var f:Number = 5.0; var i:int = f as int; // i は 5
式がデータ型に属さない場合、as は値を変換せず null を返します。そのため、キャストのようにランタイムエラーが起きないという利点があります。ただし、基本データ型 (Boolean, Number, int, uint) の値の変換が目的の場合には向きません。
var f:Number = 5.5; var i:int = f as int; // i は 0 trace(f as int); // null が出力される
instanceof
Java では、ある変数が特定の型に属しているかを知る場合 instanceof を使います。
String str; if (str instanceof Number) { ... }
AS3 は、このような場合 is 演算子を使います。
var str:String; if (str is Number) { ... }
宣言
変数
Java は以下のように変数宣言をします。
public int foo; public Object bar = new Object();
AS3 では以下のように、var キーワードを使います。型は変数名の後に ":" を挟んで付けます。変数宣言は Java と大きく違う点の 1 つです。
public var foo:int; public var bar:Object = new Object();
関数
Java は以下のように関数を宣言します。
public int foo(String str);
AS3 では function キーワードを使います。変数の宣言と同様に ":" の後に型を指定します。
public function foo(str:String):int;
スコープ
Java はブロックが変数のスコープになります。下の 2 つの for ブロック内の i は別の変数として扱われます。
public void foo() { for (int i = 0; i < 10; ++i) {} for (int i = 0; i < 5; ++i) {} }
AS3 にはブロックスコープがありません。関数が最小のスコープ単位になります。下のように、ブロック内では変数宣言を記述しないようにするのが推奨です。
public function foo():void { var i:int; for (i = 0; i < 10; ++i) {} for (i = 0; i < 5; ++i) {} }
Final と const
Java には final というキーワードがあります。定数を宣言したい場合に使えます。
public static final int FOO = 5;
AS3 で定数を宣言する場合は const を使います。var が不要なことに注意してください。
public static const FOO:int = 5;
配列
Java の配列は大きさと型が決まっています。
int myArray[] = new int[5];
AS3 の配列は、型を指定することが出来ません。また大きさも動的に変化します。
var myArray:Array = new Array(5);
myArray[0] = 0; myArray[9] = "foo";
配列の初期化
Java の配列は、初期化子を使って宣言することができます。大きさは、指定した要素数に固定されます。
int myArray[] = {0, 1, 2};
AS3 の場合は、[] を使って初期化子を指定します。大きさも型も不定です。
var myArray:Array = ["zero", 1, "2"];
myArray[9] = "きゅう";
ジェネリクスとコレクション
Java では汎用のコレクションと型の指定されたコレクションが使えます。
List<String> myList = new ArrayList<String>(); myList.add("foo"); String foo = myList.get(0);
AS3 には同等の機能はありません。が、Vector を使って型の指定された配列を使うことが出来ます。<> の前にドット (.) があることに注意してください。
var myList:Vector.<String> = new Vector.<String>(); myList.push("foo"); var foo:String = myList[0];
XML
Java では、XML は JAXP, JAXB, SAX, Xerces, JDOM などの様々なライブラリを使って処理します。
AS3 は E4X を使います。E4X は言語に組み込まれているため、別途ライブラリを必要としません。スクリプト内に直接 XML 文を書いて初期化できます。
var myXML:XML = <order><item>beer</item></order>; var item:String = myXML.item;
E4X について、詳しくは XML の操作をご覧ください。
正規表現
Java で正規表現を使うには、java.util.regex パッケージを使用します。
Pattern pattern = Pattern.compile("\d+");
Matcher matcher = pattern.matcher("foo");
if (matcher.matches()) { ... }
AS3 では RegExp クラスを使用します。直接スクリプト内に正規表現を書いて初期化することができます。
var pattern:RegExp = /\d+/; var str:String = "foo";
if (pattern.test(str)) { ... }
アノテーションとメタデータ
Java はアノテーションが使用できます。
@Meta1 public class Foo { @Meta2 String bar; }
AS3 では同様の目的でメタデータが使用できます。
[Meta1] public class Foo { [Meta2] var bar:String; }
パッケージ
Java はパッケージ名をファイル内に宣言します。Java のパッケージ宣言はファイル全体で有効です。
package foo; class Foo {}
AS3 は、クラスをパッケージブロック内に宣言します。AS3 では、複数のパッケージ定義を 1 つのファイルで行うことが可能です。
package foo { class Foo {} }
名前空間
Java では、パッケージに属する範囲を名前空間と呼ぶのが一般的です。
package my.package;
AS3 では、名前空間はパッケージとは異なる概念です。パッケージは名前の競合を避けるため、名前空間は属性やメソッドのアクセス制御に使われます。名前空間は namespace を使って宣言します。
package my.package { namespace my_space; }
アクセスレベル
Java ではアクセス修飾子を使って以下の 4 種類のアクセスレベルを設定することができます。
- public: すべてのクラスとパッケージからアクセス可能
- protected: 同一パッケージ内とサブクラスからアクセス可能
- 修飾子なし: 同一パッケージ内からアクセス可能
- private: 同一クラス内からアクセス可能
AS3 では、名前空間を可視性の制御に使用します。標準で定義されている名前空間には以下のものがあります。
- public: すべてのクラスとパッケージからアクセス可能
- protected: 同一クラス内とサブクラスからアクセス可能
- internal: 同一パッケージ内からアクセス可能
- 指定なし: 同一パッケージ内からアクセス可能
- private: 同一クラス内からアクセス可能
名前空間が宣言されていないと、internal として扱われます。Java と異なるのは、protected が同一パッケージ内からでもサブクラス以外はアクセスできない点です。
Java と ActionScript 3 の違い: クラス宣言編に続く