R5 3 type annotation

59
© 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

Transcript of R5 3 type annotation

Page 1: 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

Page 2: R5 3 type annotation

某メーカー/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

木村 って、どこのどいつ ?

Page 3: R5 3 type annotation

© 2013 EIICHI KIMURA. All Rights Reserved. 3

Annotation について

2013/5/11 15:15-16:05

Page 4: R5 3 type annotation

Java 5 から導入されたアノテーション

使ったことありますか ?

@Deprecated

@Override

@SupressWarnings

@SafeVarargs(Java SE 7 から)

© 2013 EIICHI KIMURA. All Rights Reserved. 4 2013/5/11 15:15-16:05

Page 5: R5 3 type annotation

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

Page 6: R5 3 type annotation

これ以外に、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

Page 7: R5 3 type annotation

もちろん、自分でも作れます ...

アノテーション型 : Annotation Type

public @interface Copyright {

String value();

}

© 2013 EIICHI KIMURA. All Rights Reserved. 7 2013/5/11 15:15-16:05

Page 8: R5 3 type annotation

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

Page 9: R5 3 type annotation

アノテーションの利用例 : 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

Page 10: R5 3 type annotation

2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 10

Type Annotation について

Page 11: R5 3 type annotation

アノテーション型 : Annotation Type

と 型アノテーション :

Type Annotation は違います !!

© 2013 EIICHI KIMURA. All Rights Reserved. 11 2013/5/11 15:15-16:05

Page 12: R5 3 type annotation

アノテーション型には 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

Page 13: R5 3 type annotation

Java SE 5~7 のアノテーションは

宣言アノテーション 宣言対象に対するアノテーションのみ

パッケージ宣言、クラス・インタフェース宣言、メソッド・コンストラクタ宣言、フィールド宣言、メソッドの仮引数宣言、ローカル変数宣言の箇所で使用できた。

(除く) ジェネリックの型パラメータ宣言

型利用に対するアノテーションはできない

© 2013 EIICHI KIMURA. All Rights Reserved. 13 2013/5/11 15:15-16:05

Page 14: R5 3 type annotation

Java SE8 で型の使用に対しても記述できるようにする

型アノテーション

宣言に対してではなく、型の利用に対して利用できる。

たとえば、型限定子として、

メソッド仮引数、メソッド返却、レシーバの型の使用に対して

ジェネリックの型パラメータ、キャストでの型の利用に対して

(除) import 文、クラスリテラル(XXX.class)、static メンバアクセスのクラス名, アノテーション ⇒ これらは、型の使用とは解釈されない。

© 2013 EIICHI KIMURA. All Rights Reserved. 14 2013/5/11 15:15-16:05

Page 15: R5 3 type annotation

2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 15

言語仕様上は ...

Page 16: R5 3 type annotation

型アノテーションを利用する構文のみ規定している

型アノテーションを利用できる構文を規定

型が使われている箇所に前置する

© 2013 EIICHI KIMURA. All Rights Reserved. 16 2013/5/11 15:15-16:05

Page 17: R5 3 type annotation

例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

Page 18: R5 3 type annotation

例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

Page 19: R5 3 type annotation

例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

Page 20: R5 3 type annotation

例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

Page 21: R5 3 type annotation

例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

Page 22: R5 3 type annotation

例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

Page 23: R5 3 type annotation

@NonNull

@Interned

@ReadOnly

@NotEmpty

@Critical

@Tainted

@Existing

使いたくなりましたか ?

2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 23

Page 24: R5 3 type annotation

型アノテーションの意味は規定しない

しかし

型アノテーションの 意味(セマンティック)は規定しない !!

つまり、利用イメージの例を紹介しましたが、

Java 言語仕様で、これらの型アノテーションの意味は規定していない。

© 2013 EIICHI KIMURA. All Rights Reserved. 24 2013/5/11 15:15-16:05

Page 25: R5 3 type annotation

型アノテーションの意味は規定しない

さらに

Java SE 8 で

事前定義された型アノテーションは

(今のところ)ない !! 型アノテーションの提供側が、

その型アノテーションと、その意味との両方を与える。

© 2013 EIICHI KIMURA. All Rights Reserved. 25 2013/5/11 15:15-16:05

Page 26: R5 3 type annotation

2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 26

Checker Framework

Page 27: R5 3 type annotation

© 2013 EIICHI KIMURA. All Rights Reserved. 27 2013/5/11 15:15-16:05

Page 28: R5 3 type annotation

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

Page 29: R5 3 type annotation

提供されるチェッカ

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

Page 30: R5 3 type annotation

© 2013 EIICHI KIMURA. All Rights Reserved. 30 2013/5/11 15:15-16:05

Page 31: R5 3 type annotation

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

Page 32: R5 3 type annotation

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

Page 33: R5 3 type annotation

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

Page 34: R5 3 type annotation

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

Page 35: R5 3 type annotation

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

Page 36: R5 3 type annotation

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

Page 37: R5 3 type annotation

© 2013 EIICHI KIMURA. All Rights Reserved. 37 2013/5/11 15:15-16:05

Page 38: R5 3 type annotation

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

Page 39: R5 3 type annotation

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

Page 40: R5 3 type annotation

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

Page 41: R5 3 type annotation

エラー部分をコメントにして、実行してみると ...

>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

Page 42: R5 3 type annotation

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

Page 43: R5 3 type annotation

エラー部分をコメントにして、実行してみると ...

>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

Page 44: R5 3 type annotation

© 2013 EIICHI KIMURA. All Rights Reserved. 44 2013/5/11 15:15-16:05

Page 45: R5 3 type annotation

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

Page 46: R5 3 type annotation

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

Page 47: R5 3 type annotation

では、要素を変更できないようにするには(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

Page 48: R5 3 type annotation

© 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

Page 49: R5 3 type annotation

では、要素を変更できないようにするには(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

Page 50: R5 3 type annotation

では、要素を変更できないようにするには

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

Page 51: R5 3 type annotation

© 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

Page 52: R5 3 type annotation

@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

Page 53: R5 3 type annotation

参照とデータ変更の関係図(前頁のコード)

© 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

Page 54: R5 3 type annotation

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

Page 55: R5 3 type annotation

//*>>> 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

Page 56: R5 3 type annotation

2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 56

Java SE 8 Early Access

Page 57: R5 3 type annotation

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

Page 58: R5 3 type annotation

型アノテーションは型の使用に対するアノテーション

実行時エラーになる前、コンパイル時にできるだけバグの芽をつむために利用できる

ただ、JDK8 で標準的な型アノテーションはない

ツールなどで用意されているものをうまく活用しよう

Checker Framework は、その選択肢の一つ

ソースコードがごちゃごちゃする感も否めない

自分で型アノテーションを作ることもできる

まとめ

2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved. 58

Page 59: R5 3 type annotation

2013/5/11 15:15-16:05 © 2013 EIICHI KIMURA. All Rights Reserved 59

おわり