【社内勉強会】Javaアノテーションの基礎(2017/11/02) ~作成中～



# 0. はじめに

-------
## 内容

* アノテーションの基礎。


### 前提知識
* Javaの基本構文
* Javaのアノテーションの使い方


-------
## 参考図書

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/7332761b-4691-5dec-bd8f-a4ae90adafdd.png)

[『Effective Java 第2版』丸善出版](https://pub.maruzen.co.jp/book_magazine/book_data/search/9784621066058.html)

-------
## 目次
1. アノテーションのメリット
2. 自作アノテーション
3. JUnit、lombokの中身を見る

-------
# 1. アノテーションのメリット

-------
## Javaのアノテーションの概要

>アノテーション（英語：annotation）とは、あるデータに対して関連する情報（メタデータ）を注釈として付与すること。

※[アノテーション - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%8E%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3) 引用

* Java5から導入された(2004年リリース）


-------
## アノテーションの例(JUnit4)

```java:CalculationTest.java
public class CalculationTest {
    /** テストケース1 */
	@Test
	public void sampleTest1() {
		//...
	}
    /** テストケース2 */
	@Test
	public void sampleTest2() {
		//...
	}    
}
```

* テストケースであることを`@Test`で表す
* JUnitのRunnerは、`@Test`が付与されたメソッドのみ実行する
* アノテーションはJUnit4から導入された

-------
## もしもJUnitでアノテーションが使えなかったら（JUnit3）

```java:CalculationTest.java
public class CalculationTest extends TestCase{
    /** テストケース1 */
	public void testSample1() {
		//...
	}
    /** テストケース2 */
	public void testSample2() {
		//...
	}    
}
```

* テストクラスであることを、`TestCase`の継承で表す
* テストケースになるメソッド名は、`test`から始まる  
⇒命名パターン

※ http://d.hatena.ne.jp/smada564/20110501/1304265351 参考

-------
## 命名パターンの短所

### 誤字に気づかない

*  メソッドが名が`tsetSample2`の場合（誤字）、実行されないだけ。エラーが出ない

### パラメータ値を紐づけられない
たとえば、`IllegalArgumentException`をスローすることを期待するテストメソッドを考える。
    
```java
/** JUnit4の書き方 */
@Test(expected = IllegalArgumentException.class)
public void sample() {
	//...
}

/** アノテーションが使えない場合の例 */
public void test_IllegalArgumentException_sample() {
	//...
}    
```    

* 醜く、脆弱
* Exceptionが存在しているかかどうかを、コンパイルは判断できない
    - 実行するまで気づかない

※『Effective Java第2版』項目35 参考

-------
## XMLとアノテーションの比較

Servletは、アノテーションとXMLどちらでも設定できる。

```java
@WebServlet("/Hello")
public class HelloServlet extends HttpServlet {
  //...
}
```


```xml:web.xml
<!-- アノテーションを使わない場合は、XMLで指定 -->
<servlet>
  <servlet-name>Hello</servlet-name>
  <servlet-class>jp.co.sample.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>Hello</servlet-name>
  <url-pattern>/Hello</url-pattern>
</servlet-mapping>
```

XMLと比較したアノテーションの特徴

* 記述量が少ない
* 一つのファイルで完結している
* クラス名やメソッド名を変更しても、アノテーションの修正は不要  

⇒ **ソースの変更に強い**

※ [Annotations vs XML, advantages and disadvantages](https://stackoverflow.com/questions/17086421/annotations-vs-xml-advantages-and-disadvantages) 参考


-------
# 標準ライブラリのアノテーション


-------
## `@Override`

オーバライドしているメソッドであることを表すアノテーション。

```java:Book.java
public class Book {
	public Book(String title, String author) {
		this.title = title;
		this.author = author;
	}
	String title;
	String author;

	@Override //Compile Error. 正しくは　equals(Object obj)
	public boolean equals(Book obj) {
		//nullチェックは省略
		return title.equals(obj.title) && author.equals(obj.author);
	}

}
```

コンパイル時に、オーバライドできていない（オーバロードしている）ことに気づける。

※『Effective Java第2版』項目36 参考
※ [【Effective Java】項目３６：常に Override アノテーションを利用する](http://hjm333.hatenablog.com/entry/2016/05/29/001029) 参考


-------
## `@Deprecated`

Java9から`@Deprecated(since="9", forRemoval=true)`という書き方ができるようになった


* 廃止予定なのか？(forRemoval)
* いつ廃止するのか？(since)

※ [What’s New for Core Libraries in JDK](https://docs.oracle.com/javase/9/whatsnew/toc.htm#JSNEW-GUID-BA9D8AF6-E706-4327-8909-F6747B8F35C5) 参考


-------
## `@SuppressWarnings`

IDEに警告メッセージを抑制させる。

```java
@SuppressWarnings( "unchecked" ) //型のチェックに関する警告を除外
@SuppressWarnings( "javadoc" ) //JavaDoc警告の除外
public class Book {
	//..
}
```


※ http://capm-network.com/?tag=Java-%E3%82%A2%E3%83%8E%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3 参照

-------
## value属性

-------
# 付録
-------
## 標準アノテーション


------
## 参考サイト

http://www.oracle.com/webfolder/technetwork/jp/javamagazine/Java-MA14-Architect-TypeAnnotations.pdf
http://www.oracle.com/webfolder/technetwork/jp/javamagazine/Java-MA16-Annotations.pdf