R5 3 type annotation
-
Upload
eiichi-kimura -
Category
Documents
-
view
1.462 -
download
2
Transcript of R5 3 type annotation
© 2013 EIICHI KIMURA. All Rights Reserved. 1
JJUG CCC 2013 Spring - [R5-3] #ccc_r53
Type Annotationって何 ? それを使うとプログラムはどう変わる ?
2013/5/11
木村英一(@kimuchi583)
2013/5/11 15:15-16:05
某メーカー/SIer で Java 技術支援や、新機能をいち早く普及展開することに精力を注いでいます。ただ、イマイチ、新しいバージョンに移ってくれないのが悩みのタネ。Java との出会いは v1.02 の頃。あれよ、あれよという間に 17年もってしまいました。乗り鉄 & 撮り鉄。
WebSite(1) ー "Java etc..." - http://kimuchi583.at.webry.info/
WebSIte(2) ー http://blog.kimu2.jp/
Tweitter ー @kimuchi583
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 2
木村 って、どこのどいつ ?
© 2013 EIICHI KIMURA. All Rights Reserved. 3
Annotation について
2013/5/11 15:15-16:05
Java 5 から導入されたアノテーション
使ったことありますか ?
@Deprecated
@Override
@SupressWarnings
@SafeVarargs(Java SE 7 から)
© 2013 EIICHI KIMURA. All Rights Reserved. 4 2013/5/11 15:15-16:05
Java 8 には 82 個のアノテーションが定義されている
© 2013 EIICHI KIMURA. All Rights Reserved. 5
ANNOTATION_TYPE
(アノテーション型)
PACKAGE
(パッケージ)
TYPE
(型・クラス)
FIELD
(フィールド)
METHOD
(メソッド)
CONSTRUCTOR
(コンストラクタ)
PARAMETER
(パラメータ)
LOCAL_VARIABLE
(ローカル変数)
TYPE_PARAMETER
(型パラメータ)
TYPE_USE
(型の利用)
型アノテーション
1 javax.xml.ws Action JAX-WS 2.1 〇 〇 〇
2 javax.xml.ws.soap Addressing JAX-WS 2.1 〇 〇 〇 〇 〇
3 javax.xml.ws BindingType JAX-WS 2.0 〇 〇 〇
4 java.beans ConstructorProperties Java SE 6 〇 〇 〇
5 java.lang Deprecated Java SE 5.0 〇 〇 〇 〇 〇 〇 〇 〇 〇 〇
6 javax.management DescriptorKey Java SE 6 〇 〇 〇
7 java.lang.annotation Documented Java SE 5.0 〇 〇 〇
8 javax.xml.ws FaultAction JAX-WS 2.1 〇 〇 〇
9 java.lang FunctionalInterface Java SE 8 〇 〇 〇
10 javax.annotation Generated Common Annotation 1.0 〇 〇 〇 〇 〇 〇 〇 〇 〇 〇
11 javax.tools.annotation GenerateNativeHeader Java SE 8 〇 〇 〇
12 javax.jws HandlerChain 〇 〇 〇 〇
13 java.lang.annotation Inherited Java SE 5.0 〇 〇 〇
14 javax.jws.soap InitParam 〇
15 javax.xml.ws.soap MTOM JAX-WS 2.1 〇 〇 〇 〇 〇 〇
16 javax.management MXBean Java SE 6 〇 〇 〇
17 java.lang.annotation Native Java SE 8 〇 〇 〇
18 javax.jws Oneway 〇 〇
19 java.lang Override Java SE 5.0 〇 〇
20 javax.annotation PostConstruct Common Annotation 1.0 〇 〇 〇
21 javax.annotation PreDestroy Common Annotation 1.0 〇 〇 〇
22 java.lang.annotation Repeatable Java SE 8 〇 〇 〇
23 javax.xml.ws RequestWrapper JAX-WS 2.0 〇 〇 〇
24 javax.annotation Resource Common Annotation 1.0 〇 〇 〇 〇
25 javax.annotation Resources Common Annotation 1.0 〇 〇 〇
26 javax.xml.ws RespectBinding JAX-WS 2.1 〇 〇 〇 〇 〇 〇
27 javax.xml.ws ResponseWrapper JAX-WS 2.0 〇 〇 〇
28 java.lang.annotation Retention Java SE 5.0 〇 〇 〇
29 java.lang SafeVarargs Java SE 7 〇 〇 〇 〇
30 javax.xml.ws ServiceMode JAX-WS 2.0 〇 〇 〇 〇
31 javax.jws.soap SOAPBinding 〇 〇 〇
32 javax.jws.soap SOAPMessageHandler 〇
33 javax.jws.soap SOAPMessageHandlers 〇 〇 〇
34 javax.annotation.processing SupportedAnnotationTypes Java SE 6 〇 〇 〇
35 javax.annotation.processing SupportedOptions Java SE 6 〇 〇 〇
36 javax.annotation.processing SupportedSourceVersion Java SE 6 〇 〇 〇
37 java.lang SuppressWarnings Java SE 5.0 〇 〇 〇 〇 〇 〇 〇
38 java.lang.annotation Target 〇 〇 〇
39 java.beans Transient Java SE 7 〇 〇
40 javax.xml.ws WebEndpoint JAX-WS 2.0 〇 〇 〇
41 javax.xml.ws WebFault JAX-WS 2.0 〇 〇 〇
42 javax.jws WebMethod 〇 〇
43 javax.jws WebParam 〇 〇
44 javax.jws WebResult 〇 〇
45 javax.jws WebService 〇 〇
46 javax.xml.ws WebServiceClient JAX-WS 2.0 〇 〇 〇
47 javax.xml.ws.spi WebServiceFeatureAnnotation JAX-WS 2.1 〇 〇 〇
48 javax.xml.ws WebServiceProvider JAX-WS 2.0 〇 〇 〇
49 javax.xml.ws WebServiceRef JAX-WS 2.0 〇 〇 〇 〇 〇
50 javax.xml.ws WebServiceRefs JAX-WS 2.0 〇 〇 〇
51 javax.xml.bind.annotation XmlAccessorOrder JAXB 2.0 〇 〇 〇 〇
52 javax.xml.bind.annotation XmlAccessorType JAXB 2.0 〇 〇 〇 〇
53 javax.xml.bind.annotation XmlAnyAttribute JAXB 2.0 〇 〇 〇
54 javax.xml.bind.annotation XmlAnyElement JAXB 2.0 〇 〇 〇
55 javax.xml.bind.annotation XmlAttachmentRef JAXB 2.0 〇 〇 〇 〇
56 javax.xml.bind.annotation XmlAttribute JAXB 2.0 〇 〇 〇
57 javax.xml.bind.annotation XmlElement JAXB 2.0 〇 〇 〇 〇
58 javax.xml.bind.annotation XmlElementDecl JAXB 2.0 〇 〇
59 javax.xml.bind.annotation XmlElementRef JAXB 2.0 〇 〇 〇
60 javax.xml.bind.annotation XmlElementRefs JAXB 2.0 〇 〇 〇
61 javax.xml.bind.annotation XmlElements JAXB 2.0 〇 〇 〇
62 javax.xml.bind.annotation XmlElementWrapper JAXB 2.0 〇 〇 〇
63 javax.xml.bind.annotation XmlEnum JAXB 2.0 〇 〇
64 javax.xml.bind.annotation XmlEnumValue JAXB 2.0 〇 〇
65 javax.xml.bind.annotation XmlID JAXB 2.0 〇 〇 〇
66 javax.xml.bind.annotation XmlIDREF JAXB 2.0 〇 〇 〇
67 javax.xml.bind.annotation XmlInlineBinaryData JAXB 2.0 〇 〇 〇 〇
68 javax.xml.bind.annotation.adapters XmlJavaTypeAdapter JAXB 2.0 〇 〇 〇 〇 〇 〇
69 javax.xml.bind.annotation.adapters XmlJavaTypeAdapters JAXB 2.0 〇 〇
70 javax.xml.bind.annotation XmlList JAXB 2.0 〇 〇 〇 〇
71 javax.xml.bind.annotation XmlMimeType JAXB 2.0 〇 〇 〇 〇
72 javax.xml.bind.annotation XmlMixed JAXB 2.0 〇 〇 〇
73 javax.xml.bind.annotation XmlNs JAXB 2.0 〇
74 javax.xml.bind.annotation XmlRegistry JAXB 2.0 〇 〇
75 javax.xml.bind.annotation XmlRootElement JAXB 2.0 〇 〇
76 javax.xml.bind.annotation XmlSchema JAXB 2.0 〇 〇
77 javax.xml.bind.annotation XmlSchemaType JAXB 2.0 〇 〇 〇 〇
78 javax.xml.bind.annotation XmlSchemaTypes JAXB 2.0 〇 〇
79 javax.xml.bind.annotation XmlSeeAlso JAXB 2.1 〇 〇
80 javax.xml.bind.annotation XmlTransient JAXB 2.0 〇 〇 〇 〇
81 javax.xml.bind.annotation XmlType JAXB 2.0 〇 〇
82 javax.xml.bind.annotation XmlValue JAXB 2.0 〇 〇 〇
@Deprecated @Documented @WebServiceFeatureAnnotation@Inherited
Java SE 8~
宣言アノテーション
@Target @Retention
Java SE 5.0 ~
# 導入バージョンRUNTIME SOURCE
アノテーション型
パッケージ アノテーション名
2013/5/11 15:15-16:05
これ以外に、Java EE など他の API でも使われています
Java EE 6 - Servlet, EJB
@EJB, @Stateless, @Stateful,
@Singleton, ...
@WebServlet, @WebFilter, @WebListener, ...
CDI
@Model, @SessionScope, @Inject, ...
JPA
@Entity, @Table, @ID, @OneToMany, ...
© 2013 EIICHI KIMURA. All Rights Reserved. 6 2013/5/11 15:15-16:05
もちろん、自分でも作れます ...
アノテーション型 : Annotation Type
public @interface Copyright {
String value();
}
© 2013 EIICHI KIMURA. All Rights Reserved. 7 2013/5/11 15:15-16:05
Java SE 5~7 で使えるアノテーション型のソース
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
@Target( // "ElementType." は省略してます ...
{ TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE }) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }
© 2013 EIICHI KIMURA. All Rights Reserved. 8 2013/5/11 15:15-16:05
アノテーションの利用例 : Java 8 のソースから引用
String クラスの コンストラクタ
@Deprecated public String(byte ascii[], int hibyte) { this(ascii, hibyte, 0, ascii.length); }
Interger クラスの hashCode メソッド
@Override public int hashCode() { return Integer.hashCode(value); }
© 2013 EIICHI KIMURA. All Rights Reserved. 9 2013/5/11 15:15-16:05
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 10
Type Annotation について
アノテーション型 : Annotation Type
と 型アノテーション :
Type Annotation は違います !!
© 2013 EIICHI KIMURA. All Rights Reserved. 11 2013/5/11 15:15-16:05
アノテーション型には 2 種類あります
宣言アノテーション
@Target が ElementType.TYPE_USE 以外のアノテーション ElementType.ANNOTATION_TYPE
ElementType.CONSTRUCTOR
ElementType.FIELD
ElementType.LOCAL_VARIABLE
ElementType.METHOD
ElementType.PACKAGE
ElementType.PARAMETER
ElementType.TYPE
ElementType.TYPE_PARAMETER : @since JDK8
型アノテーション @Target が ElementType.TYPE_USE のアノテーション
© 2013 EIICHI KIMURA. All Rights Reserved. 12 2013/5/11 15:15-16:05
Java SE 5~7 のアノテーションは
宣言アノテーション 宣言対象に対するアノテーションのみ
パッケージ宣言、クラス・インタフェース宣言、メソッド・コンストラクタ宣言、フィールド宣言、メソッドの仮引数宣言、ローカル変数宣言の箇所で使用できた。
(除く) ジェネリックの型パラメータ宣言
型利用に対するアノテーションはできない
© 2013 EIICHI KIMURA. All Rights Reserved. 13 2013/5/11 15:15-16:05
Java SE8 で型の使用に対しても記述できるようにする
型アノテーション
宣言に対してではなく、型の利用に対して利用できる。
たとえば、型限定子として、
メソッド仮引数、メソッド返却、レシーバの型の使用に対して
ジェネリックの型パラメータ、キャストでの型の利用に対して
(除) import 文、クラスリテラル(XXX.class)、static メンバアクセスのクラス名, アノテーション ⇒ これらは、型の使用とは解釈されない。
© 2013 EIICHI KIMURA. All Rights Reserved. 14 2013/5/11 15:15-16:05
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 15
言語仕様上は ...
型アノテーションを利用する構文のみ規定している
型アノテーションを利用できる構文を規定
型が使われている箇所に前置する
© 2013 EIICHI KIMURA. All Rights Reserved. 16 2013/5/11 15:15-16:05
例1. クラス周りでは
コンストラクタ呼出し(オブジェクト生成)
new @Interned MyObject()
new @NonEmpty @Readonly List<String>(myNonEmptyStringSet)
myVar . new @Tainted NestedClass()
クラス継承
class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... }
© 2013 EIICHI KIMURA. All Rights Reserved. 17 2013/5/11 15:15-16:05
例2. 式・文まわりでは
throws 句
void monitorTemperature() throws @Critical TemperatureException { ... }
キャスト式
myString = (@NonNull String) myObject;
instanceof 式(型検査)
boolean isNonNull = myString instanceof @NonNull String;
© 2013 EIICHI KIMURA. All Rights Reserved. 18 2013/5/11 15:15-16:05
例3. ジェネリック周り では ...
ジェネリッククラスの型アーギュメント Map<@NonNull String, @NonEmpty List<@Readonly Document>> files;
ジェネリックメソッド・コンストラクタ呼出し時の型アーギュメ
ント o.<@NonNull String>m("...");
ジェネリックの型制約(bounds)
class Folder<F extends @Existing File> { ... }
Collection<? super @Existing File>
© 2013 EIICHI KIMURA. All Rights Reserved. 19 2013/5/11 15:15-16:05
例4. 配列周りでは ... 指定場所で意味が変わる
@Readonly Doc[][] d1 = new @Readonly Doc [2][12];
// "read-only な Doc" の配列の配列
Doc @Readonly [][] d2 = new Doc @Readonly [2][12];
// Doc の配列の "read-only な配列"
Doc[] @Readonly [] d3 = new Doc[2] @Readonly [12];
// Doc の "read-only な配列" の配列
© 2013 EIICHI KIMURA. All Rights Reserved. 20 2013/5/11 15:15-16:05
例5. レシーバ用にメソッド引数宣言の構文が拡張 !
インスタンスメソッドのレシーバ(this) [通常のコード] は this を引数に書かない
class MyClass { ... public String toString() { ... } public boolean equals(Object other) { ... } }
[レシーバに型アノテーションを指定する] ときは this 引数宣言する
class MyClass { ... public String toString(@Readonly MyClass this) { ... } public boolean equals(@Readonly MyClass this, @Readonly Object other) { ... } }
© 2013 EIICHI KIMURA. All Rights Reserved. 21 2013/5/11 15:15-16:05
例6. 型利用でない場所 - 型アノテーションが書けず!!
アノテーション型に対するアノテーション
クラスリテラル
Class c = @NonNull Integer.class; // NG Class c = Integer @NonNull[].class; // NG
import 文
import java.lang.@Interned String; // NG import @Interned java.lang.String; // NG
static メンバアクセス
@Interned String . valueOf(10); // NG
© 2013 EIICHI KIMURA. All Rights Reserved. 22 2013/5/11 15:15-16:05
@NonNull
@Interned
@ReadOnly
@NotEmpty
@Critical
@Tainted
@Existing
使いたくなりましたか ?
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 23
型アノテーションの意味は規定しない
しかし
型アノテーションの 意味(セマンティック)は規定しない !!
つまり、利用イメージの例を紹介しましたが、
Java 言語仕様で、これらの型アノテーションの意味は規定していない。
© 2013 EIICHI KIMURA. All Rights Reserved. 24 2013/5/11 15:15-16:05
型アノテーションの意味は規定しない
さらに
Java SE 8 で
事前定義された型アノテーションは
(今のところ)ない !! 型アノテーションの提供側が、
その型アノテーションと、その意味との両方を与える。
© 2013 EIICHI KIMURA. All Rights Reserved. 25 2013/5/11 15:15-16:05
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 26
Checker Framework
© 2013 EIICHI KIMURA. All Rights Reserved. 27 2013/5/11 15:15-16:05
v1.6.3 - 2013/5/1 版
http://types.cs.washington.edu/checker-framework/
Windows 版の起動方法
java -jar %CHECKERS%¥binary¥checkers.jar
-processor checkers.nullness.NullnessChecker
xxx.java
java は JDK6, JDK7 でも OK !!
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 28
Checker Framework
提供されるチェッカ
1. Nullness checker : ヌルポインターエラーチェック用
2. Interning checker : intern 化と等価検査エラーチェック用
3. Lock checker :並行処理とロック関連エラーチェック用
4. Fake enum checker : 型安全 enum パターンの許可向け
5. Tainting checker : 信頼性とセキュリティエラーチェック用
6. Regex checker : 構文不正の正規表現チェック用
7. Property file checker : プロパティ、リソースバンドル利用時の妥当にキーを使用しているかのチェック用(国際化含)。
8. Signature string checker : 型の文字列表現を適切に利用しているかのチェック用(Class.forName()など)。
9. Units checker : 正しい計測単位で処理されているかのチェック用
10. Linear checker : 別名及び、再利用の制御向け
11. IGJ checker : 可変エラー(不正な副作用)向け(IGJ 型システム)
12. Javari checker : 可変エラー(不正な副作用)向け(Javari型システム)
13. Basic checker : カスタマイズ検査用
14. Typestate checker : オブジェクトの正しい状態で処理が行われているかのチェック用
15.その他
© 2013 EIICHI KIMURA. All Rights Reserved. 29 2013/5/11 15:15-16:05
© 2013 EIICHI KIMURA. All Rights Reserved. 30 2013/5/11 15:15-16:05
Null Pointer Exception !! - 従来は実行時エラー
public class GetStarted1 { public static void main(String args[]) { new GetStarted1().sample(); } void sample() { Object o_ref = null; String s_ref = o_ref.toString(); } }
> javac GetStarted1.java > java GetStarted1 Exception in thread "main" java.lang.NullPointerException at GetStarted1.sample(GetStarted1.java:9) at GetStarted1.main(GetStarted1.java:5)
© 2013 EIICHI KIMURA. All Rights Reserved. 31 2013/5/11 15:15-16:05
Nullness Checker - NonNull チェック(参照)
import checkers.nullness.quals.*; public class GetStarted1 { // main()は割愛 void sample() { Object o_ref = null; String s_ref = o_ref.toString(); } }
> java -jar %CHECKERS%¥binary¥checkers.jar -processor checkers.nullness.NullnessChecker GetStarted1.java GetStarted1.java:6: エラー: dereference of possibly-null reference ref String s_ref = o_ref.toString(); ^ エラー1個
© 2013 EIICHI KIMURA. All Rights Reserved. 32 2013/5/11 15:15-16:05
Nullness Checker - NonNull チェック(代入)
import checkers.nullness.quals.*; public class GetStarted1 { // main()は割愛 void sample() { @NonNull Object o_ref = null; String s_ref = o_ref.toString(); } } java -jar %CHECKERS%¥binary¥checkers.jar -processor checkers.nullness.NullnessChecker GetStarted1.java
GetStarted1.java:5: エラー: incompatible types in assignment. @NonNull Object ref = null; ^ found : null required: @NonNull Object エラー1個
© 2013 EIICHI KIMURA. All Rights Reserved. 33 2013/5/11 15:15-16:05
Nullness Checker - 冗長コードの指摘
import checkers.nullness.quals.*; public class GetStarted1 { // main()は割愛 void sample() { @NonNull String s_ref = "xxxx"; if(s_ref != null) System.out.println(s_ref); } }
java -jar %CHECKERS%¥binary¥checkers.jar -Alint -processor checkers.nullness.NullnessChecker GetStarted1.java
GetStarted1.java:9: 警告: redundant check; "ref" is non-null if (ref != null) { System.out.println(ref.toString()); } ^ 警告1個
© 2013 EIICHI KIMURA. All Rights Reserved. 34 2013/5/11 15:15-16:05
Nullness Checker - 冗長コードの指摘
import checkers.nullness.quals.*; public class GetStarted1 { // main()は割愛 @Nullable String getXXXX() { return "xxxx"; } void sample() { @NonNull String s_ref = getXXXX(); } } java -jar %CHECKERS%¥binary¥checkers.jar -processor checkers.nullness.NullnessChecker GetStarted1.java
GetStarted1.java:11: エラー: incompatible types in assignment. @NonNull String ref = getXXXX(); ^ found : @Nullable String required: @NonNull String エラー1個
© 2013 EIICHI KIMURA. All Rights Reserved. 35 2013/5/11 15:15-16:05
Nullness Checker - 警告抑制
import checkers.nullness.quals.*; public class GetStarted1 { // main()は割愛 @Nullable String getXXXX() { return "xxxx"; } @SuppressWarnings("nullness") void sample() { @NonNull String s_ref = getXXXX(); } }
java -jar %CHECKERS%¥binary¥checkers.jar -processor checkers.nullness.NullnessChecker GetStarted1.java
© 2013 EIICHI KIMURA. All Rights Reserved. 36 2013/5/11 15:15-16:05
© 2013 EIICHI KIMURA. All Rights Reserved. 37 2013/5/11 15:15-16:05
Interning Checker
import checkers.interning.quals.*;
public class InternedTest {
public static void main(String aegs[]) {
@Interned String s1 = new @Interned String("aaa");
@Interned String s2 = new @Interned String("aaa");
String s3 = new String("aaa");
if(s1 == s2) { System.out.println("s1 == s2"); }
if(s1 == s3) { System.out.println("s1 == s3"); }
if(s2 == s3) { System.out.println("s2 == s3"); }
if(s1.equals(s2)) { System.out.println("s1.equlas(s2)");}
if(s1.equals(s3)) { System.out.println("s1.equlas(s3)"); }
if(s2.equals(s3)) { System.out.println("s2.equlas(s3)"); }
}
}
© 2013 EIICHI KIMURA. All Rights Reserved. 38 2013/5/11 15:15-16:05
java -jar %CHECKERS%¥binary¥checkers.jar -processor checkers.interning.InternedChecker InternedTest.java
InternedTest.java:10: エラー: attempting to use a non-@Interned comparison operand if(s1 == s3) { System.out.println("s1 == s3"); } ^ found: String InternedTest.java:11: エラー: attempting to use a non-@Interned comparison operand if(s2 == s3) { System.out.println("s2 == s3"); } ^ found: String InternedTest.java:12: 警告: use of .equals can be safely replaced by ==/!= if(s1.equals(s2)) { System.out.println("s1.equlas(s2)");} ^ エラー2個 警告1個
© 2013 EIICHI KIMURA. All Rights Reserved. 39 2013/5/11 15:15-16:05
Interning Checker
import checkers.interning.quals.*;
public class InternedTest {
public static void main(String aegs[]) {
@Interned String s1 = new @Interned String("aaa");
@Interned String s2 = new @Interned String("aaa");
String s3 = new String("aaa");
if(s1 == s2) { System.out.println("s1 == s2"); }
// if(s1 == s3) { System.out.println("s1 == s3"); }
// if(s2 == s3) { System.out.println("s2 == s3"); }
if(s1.equals(s2)) { System.out.println("s1.equlas(s2)");}
if(s1.equals(s3)) { System.out.println("s1.equlas(s3)"); }
if(s2.equals(s3)) { System.out.println("s2.equlas(s3)"); }
}
}
© 2013 EIICHI KIMURA. All Rights Reserved. 40 2013/5/11 15:15-16:05
エラー部分をコメントにして、実行してみると ...
>java InternedTest
s1.equlas(s2) s1.equlas(s3) s2.equlas(s3)
"s1 == s2" が表示さない !!
@Interned 同士の "==" は false つまり、"s1 != s2" である。
実行時の結果保証まではしない !!
© 2013 EIICHI KIMURA. All Rights Reserved. 41 2013/5/11 15:15-16:05
Interning Checker
import checkers.interning.quals.*;
public class InternedTest {
public static void main(String aegs[]) {
@Interned String s1 = (new String("aaa")).intern();
@Interned String s2 = (new String("aaa")).intern();
String s3 = new String("aaa");
if(s1 == s2) { System.out.println("s1 == s2"); }
// if(s1 == s3) { System.out.println("s1 == s3"); }
// if(s2 == s3) { System.out.println("s2 == s3"); }
if(s1.equals(s2)) { System.out.println("s1.equlas(s2)");}
if(s1.equals(s3)) { System.out.println("s1.equlas(s3)"); }
if(s2.equals(s3)) { System.out.println("s2.equlas(s3)"); }
}
}
© 2013 EIICHI KIMURA. All Rights Reserved. 42 2013/5/11 15:15-16:05
エラー部分をコメントにして、実行してみると ...
>java InternedTest
s1 == s2 s1.equlas(s2) s1.equlas(s3) s2.equlas(s3)
intern()を呼出すのはプログラマの責任
© 2013 EIICHI KIMURA. All Rights Reserved. 43 2013/5/11 15:15-16:05
© 2013 EIICHI KIMURA. All Rights Reserved. 44 2013/5/11 15:15-16:05
final フィールドって、何が final - エラーになるのは ?
public class ImmutableTest1 { static final int[][] iaa = new int[10][10]; static { for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { iaa[i][j] = i*10 + j; } } }
public static void main(String args[]) { iaa[0][0] = 100; // (1) iaa[1] = new int[10]; // (2) iaa = new int[10][10]; // (3) } }
© 2013 EIICHI KIMURA. All Rights Reserved. 45 2013/5/11 15:15-16:05
ImmutableTest1.java:14: エラー: final変数iaaに値を代入することはできません iaa = new int[10][10]; //(3) ^ エラー1個
© 2013 EIICHI KIMURA. All Rights Reserved. 46
iaa [0]
[1]
[2]
[3]
[9]
[0][0]
[0][1]
[0][2]
[0][3]
[0][9]
[1][0]
[1][1]
[1][2]
[1][3]
[1][9]
[2][0]
[2][1]
[2][2]
[2][3]
[2][9]
[3][0]
[3][1]
[3][2]
[3][3]
[3][9]
[9][0]
[9][1]
[9][2]
[9][3]
[9][9]
: ...
...
...
...
...
...
: : : : : :
[0]
[1]
[2]
[3]
[9]
[0][0]
[0][1]
[0][2]
[0][3]
[0][9]
[1][0]
[1][1]
[1][2]
[1][3]
[1][9]
[2][0]
[2][1]
[2][2]
[2][3]
[2][9]
[3][0]
[3][1]
[3][2]
[3][3]
[3][9]
[9][0]
[9][1]
[9][2]
[9][3]
[9][9]
: ...
...
...
...
...
...
: : : : : :
ここが
final
2013/5/11 15:15-16:05
では、要素を変更できないようにするには(1)
public class ImmutableTest1 { static final int @ReadOnly[][] iaa = new int[10][10]; public static void main(String args[]) { iaa[0][0] = 100; // (1) iaa[1] = new int[10]; // (2) // iaa = new int[10][10]; // (3) } } ImmutableTest2.java:17: エラー: Cannot (re-)assign iaa through the reference: @IGJBottom int @ReadOnly [] @Mutable [] iaa[1] = new int[10]; // (2) ^ エラー1個
© 2013 EIICHI KIMURA. All Rights Reserved. 47 2013/5/11 15:15-16:05
© 2013 EIICHI KIMURA. All Rights Reserved. 48
iaa [0]
[1]
[2]
[3]
[9]
[0][0]
[0][1]
[0][2]
[0][3]
[0][9]
[1][0]
[1][1]
[1][2]
[1][3]
[1][9]
[2][0]
[2][1]
[2][2]
[2][3]
[2][9]
[3][0]
[3][1]
[3][2]
[3][3]
[3][9]
[9][0]
[9][1]
[9][2]
[9][3]
[9][9]
: ...
...
...
...
...
...
: : : : : :
[0]
[1]
[2]
[3]
[9]
[0][0]
[0][1]
[0][2]
[0][3]
[0][9]
[1][0]
[1][1]
[1][2]
[1][3]
[1][9]
[2][0]
[2][1]
[2][2]
[2][3]
[2][9]
[3][0]
[3][1]
[3][2]
[3][3]
[3][9]
[9][0]
[9][1]
[9][2]
[9][3]
[9][9]
: ...
...
...
...
...
...
: : : : : :
ここが
final
ここが
@ReadOnly
2013/5/11 15:15-16:05
では、要素を変更できないようにするには(2)
public class ImmutableTest1 { static final int @ReadOnly[] @ReadOnly[] iaa = new int[10][10]; public static void main(String args[]) { iaa[0][0] = 100; // (1) iaa[1] = new int[10]; // (2) // iaa = new int[10][10]; // (3) } }
© 2013 EIICHI KIMURA. All Rights Reserved. 49 2013/5/11 15:15-16:05
では、要素を変更できないようにするには
ImmutableTest2.java:16: エラー: Cannot (re-)assign iaa through the reference: @IGJBottom int @ReadOnly [] iaa[0][0] = 100; // (1) ^ ImmutableTest2.java:17: エラー: Cannot (re-)assign iaa through the reference: @IGJBottom int @ReadOnly [] @ReadOnly [] iaa[1] = new int[10]; // (2)
^ エラー2個
© 2013 EIICHI KIMURA. All Rights Reserved. 50 2013/5/11 15:15-16:05
© 2013 EIICHI KIMURA. All Rights Reserved. 51
iaa [0]
[1]
[2]
[3]
[9]
[0][0]
[0][1]
[0][2]
[0][3]
[0][9]
[1][0]
[1][1]
[1][2]
[1][3]
[1][9]
[2][0]
[2][1]
[2][2]
[2][3]
[2][9]
[3][0]
[3][1]
[3][2]
[3][3]
[3][9]
[9][0]
[9][1]
[9][2]
[9][3]
[9][9]
: ...
...
...
...
...
...
: : : : : :
[0]
[1]
[2]
[3]
[9]
[0][0]
[0][1]
[0][2]
[0][3]
[0][9]
[1][0]
[1][1]
[1][2]
[1][3]
[1][9]
[2][0]
[2][1]
[2][2]
[2][3]
[2][9]
[3][0]
[3][1]
[3][2]
[3][3]
[3][9]
[9][0]
[9][1]
[9][2]
[9][3]
[9][9]
: ...
...
...
...
...
...
: : : : : :
ここが
final
ここが
@ReadOnly
ここも
@ReadOnly
2013/5/11 15:15-16:05
@Immutable vs. @ReadOnly
@Immutable はインスタンスの内容の変更ができない
@ReadOnly は、その参照を通してのみ内容変更ができない。
© 2013 EIICHI KIMURA. All Rights Reserved. 52 2013/5/11 15:15-16:05
GregorianCalendar gc2 = new GregorianCalendar(); GregorianCalendar gc3 = new GregorianCalendar(); @Immutable GregorianCalendar im_gc1 = new @Immutable GregorianCalendar(); // OK @Immutable GregorianCalendar im_gc2 = gc2; // NG @ReadOnly GregorianCalendar ro_gc = gc3; // OK
gc2.add(Calendar.DAY_OF_MONTH, 1); // OK gc3.add(Calendar.DAY_OF_MONTH, 1); // OK ro_gc.add(Calendar.DAY_OF_MONTH, 1); // NG
参照とデータ変更の関係図(前頁のコード)
© 2013 EIICHI KIMURA. All Rights Reserved. 53
gc2
gc3
Gregorian
Calendar
Gregorian
Calendar
im_gc1 Gregorian
Calendar
@Immutable
im_gc2
@Immutable
@Immutable
ro_gc
@ReadOnly
参照 OK
変更 OK
参照 OK
変更 OK
参照 NG
変更 ---
参照 OK
変更 NG
参照 OK
変更 NG
2013/5/11 15:15-16:05
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 54
無印(@Mutable) vs @ReadOnly vs. @Immutable
g_cal Gregorian
Calendar
im_g_cal Gregorian
Calendar
@Immutable
@Immutable
ro_g_cal
参照 OK
変更 OK
参照 OK
変更 NG
Gregorian
Calendar
@ReadOnly
参照 OK
変更 NG
@ReadOnly
参照 OK
変更 NG
参照 OK
変更 NG
//*>>> import checkers.nullness.quals.*;*/ public class GetStarted1 { // main()は割愛 void sample() { /*@NonNull*/ Object o_ref = null; String s_ref = o_ref.toString(); } }
class MyClass { ... public String toString(/*>>> @Readonly MyClass this*/) { ... } public boolean equals(/*>>> @Readonly MyClass this, @Readonly*/ Object other) { ... } }
Checker Framework は JDK7 でも使える
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 55
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 56
Java SE 8 Early Access
Java SE 8 Early Access
Java SE 8 Early Access b89('13/5/9現在)
http://jdk8.java.net/download.html
Type Annotation を作れます
Type Annotation 構文を認識します
型アノテーションを記述していなくても this 引数をインスタンスメソッドの最初に引数に記述できる
© 2013 EIICHI KIMURA. All Rights Reserved. 57 2013/5/11 15:15-16:05
型アノテーションは型の使用に対するアノテーション
実行時エラーになる前、コンパイル時にできるだけバグの芽をつむために利用できる
ただ、JDK8 で標準的な型アノテーションはない
ツールなどで用意されているものをうまく活用しよう
Checker Framework は、その選択肢の一つ
ソースコードがごちゃごちゃする感も否めない
自分で型アノテーションを作ることもできる
まとめ
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 58
2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved 59
おわり