- ヤング
- 会議室デビュー日: 2002/12/17
- 投稿数: 4
|
投稿日時: 2005-03-22 13:42
J2SE5.0(Tiger)でAnnotationを学習している最中なのですが、
「Annotationの値を検証した際に、不正な値であった場合に、どうすべきか?」
ということで悩んでいます。
こんなコードがあったとします。
(1)MyBirthDay.java
コード: |
|
@BirthDay(year="1999", month="9", day="19")
public class MyBirthDay {
}
|
(2)BirthDay.java
コード: |
|
public @interface BirthDay {
String year();
String month();
String day();
}
|
(1)のように、誕生日が1999年9月19日ならいいのですが、
たとえばこんなこと↓したらどうしましょう?
(1')YourBirthDay.java
コード: |
|
@BirthDay(year="9999", month="99", day="X")
public class YourBirthDay {
}
|
西暦9999年に人類がJavaを使っているか分かりませんし(というかそれ以前に滅亡してなきゃいいけど… )、
「99月」とか、「X日」という値は不正ですよね。
私が思うに、こういう場合はまず
- 警告を発しない。
- コンパイル時(javacコマンドなど)に警告を発する。
- 実行時(javaコマンドなど)に警告を発する。
のうち、まあ少なくとも、「警告を発しない。」はないかな、とも思いますが、
では、コンパイル時または実行時に警告を発するとしても、
- コンソール上で警告を発する。
- ログファイルに警告を出力する。
- com.sun.mirror.apt.AnnotationProcessor実装クラスにて、java.lang.annotation.AnnotationFormatError(を継承したクラス)を投げる。
のどれかではないか、と。
特に、「AnnotationFormatErrorを投げる説」は、processメソッドが何もthrowsしないところをみても、対応できるんではないかな、と思うんですが。
以下に、上記コードのためのAnnotationProcessorおよびAnnotationProcessorFactory実装クラスのサンプルも挙げておきます。
(3)BirthDayProcessor.java
コード: |
|
import java.io.*;
import java.util.*;
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import com.sun.mirror.type.*;
import com.sun.mirror.util.*;
public class BirthDayProcessor implements AnnotationProcessor {
AnnotationProcessorEnvironment env;
Set<AnnotationTypeDeclaration> atds;
List<String> lines = new ArrayList<String>();
BirthDayProcessor( Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env ) {
this.atds = atds;
this.env = env;
}
public void process() {
Collection<TypeDeclaration> tds
= env.getSpecifiedTypeDeclarations();
TypeDeclaration td = tds.iterator().next();
Collection<AnnotationMirror> ams
= td.getAnnotationMirrors();
AnnotationMirror am = ams.iterator().next();
Map<AnnotationTypeElementDeclaration, AnnotationValue> map
= am.getElementValues();
Set<AnnotationTypeElementDeclaration> keys
= map.keySet();
for( AnnotationTypeElementDeclaration key : keys ) {
if( key.getSimpleName().equals( "year" ) ) {
// ここで「year」の値をチェックする。
}
else if( key.getSimpleName().equals( "month" ) ) {
// ここで「month」の値をチェックする。
}
else if( key.getSimpleName().equals( "day" ) ) {
// ここで「day」の値をチェックする。
}
}
}
}
|
(4)BirthDayProcessorFactory.java
コード: |
|
import java.util.*;
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
public class BirthDayProcessorFactory
implements AnnotationProcessorFactory {
private static final Collection<String> types
= Collections.unmodifiableCollection(Arrays.asList( "BirthDay") );
private static final Collection<String> options
= Collections.emptySet();
public Collection<String> supportedAnnotationTypes() {
return types;
}
public Collection<String> supportedOptions() {
return options;
}
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env ) {
return new BirthDayProcessor( atds, env );
}
}
|
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/annotation/AnnotationFormatError.html
http://java.sun.com/j2se/1.5.0/ja/docs/ja/guide/apt/mirror/com/sun/mirror/apt/AnnotationProcessor.html
http://java.sun.com/j2se/1.5.0/ja/docs/ja/guide/apt/mirror/com/sun/mirror/apt/AnnotationProcessorFactory.html
|