javax.lang.model.util.AbstractTypeVisitor6는 Java 언어에서 타입(ElementKind.TYPE)에 대한 방문자 패턴(Visitor Pattern)을 구현하는 유틸리티 클래스입니다.
방문자 패턴은 객체 지향 디자인 패턴 중 하나로, 구조와 기능을 분리하여 확장성을 높이는 데 유용합니다. 이 패턴은 다음과 같은 경우에 사용됩니다.
- 여러 종류의 객체가 있고, 이 객체들의 행동이 다양하게 변화해야 할 때
- 객체의 구조를 변경하지 않고 새로운 동작을 추가하거나 수정해야 할 때
AbstractTypeVisitor6 클래스는 타입에 대한 메서드를 포함하는 추상 클래스입니다. 이 클래스를 상속받는 클래스를 만들고, 필요한 메서드를 오버라이드하여 새로운 동작을 추가하거나 수정할 수 있습니다.
AbstractTypeVisitor6 클래스의 메서드는 다음과 같습니다.
- visitDeclared(DeclaredType t, P p) : 선언된 타입(클래스, 인터페이스, enum 등)을 방문할 때 호출됩니다.
- visitArray(ArrayType t, P p) : 배열 타입을 방문할 때 호출됩니다.
- visitTypeVariable(TypeVariable t, P p) : 타입 변수를 방문할 때 호출됩니다.
- visitWildcard(WildcardType t, P p) : 와일드카드 타입을 방문할 때 호출됩니다.
- visitIntersection(IntersectionType t, P p) : 타입의 교차(Intersection)을 방문할 때 호출됩니다.
- visitUnion(UnionType t, P p) : 타입의 합집합(Union)을 방문할 때 호출됩니다.
AbstractTypeVisitor6 클래스를 상속받은 클래스에서는 이 메서드들을 오버라이드하여, 각 타입에 대한 동작을 구현할 수 있습니다.
예를 들어, 다음과 같이 AbstractTypeVisitor6 클래스를 상속받은 클래스를 만들 수 있습니다.
class MyTypeVisitor extends AbstractTypeVisitor6<Void, Void> {
@Override
public Void visitDeclared(DeclaredType t, Void p) {
// 선언된 타입을 방문할 때 실행될 코드
return super.visitDeclared(t, p);
}
@Override
public Void visitArray(ArrayType t, Void p) {
// 배열 타입을 방문할 때 실행될 코드
return super.visitArray(t, p);
}
// 나머지 메서드들도 오버라이드할 수 있습니다.
}
AbstractTypeVisitor6 클래스는 Java 6에서 도입되었으며, 타입(ElementKind.TYPE)에 대한 방문자 패턴을 구현하는 데 사용됩니다. 따라서 Java 6 이상에서만 사용할 수 있습니다.AbstractTypeVisitor6 클래스의 두 번째 타입 인자는 방문자 패턴에서 사용하는 데이터의 타입입니다. 보통 이 인자는 각 메서드에서 처리할 데이터를 전달하는 데 사용됩니다. 만약 데이터를 사용하지 않는다면 Void 타입을 사용할 수 있습니다.
AbstractTypeVisitor6 클래스는 다른 유틸리티 클래스와 함께 사용될 때 매우 유용합니다. 예를 들어, javax.lang.model.util.ElementScanner6 클래스를 사용하면 Java 소스 코드의 요소(Element)를 스캔할 수 있습니다. 이때 AbstractTypeVisitor6 클래스를 상속받은 클래스를 만들어서 ElementScanner6 클래스에서 사용할 수 있습니다.
아래는 AbstractTypeVisitor6 클래스를 사용하는 간단한 예시입니다.
import javax.lang.model.type.*;
import javax.lang.model.util.*;
class MyElementScanner extends ElementScanner6<Void, Void> {
public MyElementScanner() {
super(new VoidVisitor<Void>(), null);
}
@Override
public Void visitType(TypeElement e, Void p) {
// TypeElement를 방문할 때 실행될 코드
e.asType().accept(new MyTypeVisitor(), null);
return super.visitType(e, p);
}
}
class MyTypeVisitor extends AbstractTypeVisitor6<Void, Void> {
@Override
public Void visitDeclared(DeclaredType t, Void p) {
// 선언된 타입을 방문할 때 실행될 코드
return super.visitDeclared(t, p);
}
@Override
public Void visitArray(ArrayType t, Void p) {
// 배열 타입을 방문할 때 실행될 코드
return super.visitArray(t, p);
}
}
public class Example {
public static void main(String[] args) {
MyElementScanner scanner = new MyElementScanner();
scanner.scan(someElement);
}
}
위 예제에서는 MyElementScanner 클래스를 만들어서 ElementScanner6 클래스에서 사용합니다. MyElementScanner 클래스에서는 TypeElement를 방문할 때 MyTypeVisitor 클래스에서 구현한 visitDeclared()와 visitArray() 메서드를 실행합니다. 이렇게 하면 TypeElement의 타입 정보에 대한 처리를 AbstractTypeVisitor6 클래스를 사용해서 처리할 수 있습니다.아래는 예제 코드입니다. 이 예제 코드는 특정 패키지 내의 클래스 파일의 이름을 출력하는 간단한 프로그램입니다. 이 프로그램은 javax.lang.model.util.ElementScanner6 클래스와 javax.lang.model.util.AbstractTypeVisitor6 클래스를 사용합니다.
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.ElementScanner6;
import javax.lang.model.util.AbstractTypeVisitor6;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Example {
public static void main(String[] args) throws IOException {
// 특정 패키지 내의 클래스 파일들을 가져옴
String packageName = "com.example.package";
List<JavaFileObject> files = new ArrayList<>();
StandardJavaFileManager fileManager = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null);
for (JavaFileObject file : fileManager.list(JavaFileObject.Kind.CLASS, packageName, ElementFilter.packageFilter())) {
files.add(file);
}
fileManager.close();
// 각 클래스 파일의 이름 출력
for (JavaFileObject file : files) {
String className = file.getName().substring(packageName.length() + 1, file.getName().length() - ".class".length()).replace('/', '.');
System.out.println(className);
TypeElement typeElement = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null).getElements().getTypeElement(className);
if (typeElement != null) {
// TypeElement 내의 각 타입 변수 출력
typeElement.asType().accept(new TypeVariableVisitor(), null);
}
}
}
private static class TypeVariableVisitor extends AbstractTypeVisitor6<Void, Void> {
@Override
public Void visitTypeVariable(TypeVariable t, Void p) {
System.out.println("\tType variable: " + t);
return null;
}
@Override
public Void visitDeclared(DeclaredType t, Void p) {
// DeclaredType 내의 각 TypeMirror에 대해 visit() 메서드 호출
for (TypeMirror arg : t.getTypeArguments()) {
arg.accept(this, null);
}
return null;
}
}
}
위 예제에서는 특정 패키지 내의 클래스 파일들의 이름을 출력하는 프로그램을 작성합니다. ElementFilter.packageFilter() 메서드를 사용해서 패키지 내의 모든 요소(Element)를 가져온 후, 각 클래스 파일의 이름을 출력합니다.
이후 TypeElement를 사용해서 각 클래스 파일의 TypeElement를 가져온 후, TypeElement의 타입 정보를 출력합니다. TypeElement.asType() 메서드를 사용해서 TypeElement의 TypeMirror를 가져온 후, AbstractTypeVisitor6 클래스를 상속받은 TypeVariableVisitor 클래스를 만들어서 TypeMirror의 타입 정보를 출력합니다.
'PT선생님의 코딩 강좌' 카테고리의 다른 글
[PT선생님][59]javax.lang.model.util.AbstractTypeVisitor8 알아보기 (0) | 2023.03.06 |
---|---|
[PT선생님][58]javax.lang.model.util.AbstractTypeVisitor7 알아보기 (0) | 2023.03.06 |
[PT선생님][56]javax.lang.model.util.AbstractTypeVisitor14 알아보기 (0) | 2023.03.05 |
[PT선생님][55]javax.swing.table.AbstractTableModel 알아보기 (0) | 2023.03.05 |
[PT선생님][54]javax.swing.AbstractSpinnerModel 알아보기 (0) | 2023.03.04 |