제어자
- 클래스, 생성자, 메소드, 필드에 추가되는 키워드로 기능을 추가하며, 타깃의 의미를 변경한다.
- 제어자는 접근 제어자와 비접근 제어자로 나뉜다.
- 접근 제어자 : public, protected, default, private
- 클래스 비접근 제어자 : abstract(인스턴스화 불가 클래스), final(상속 불가 클래스), static, interface(인터페이스 또한 클래스 제어자)
- 메소드 비접근 제어자 : abstract, final, static, syncronized, native(메소드가 다른 언어로 구현)
- 필드 비접근 제어자 : final, static, transient(직렬화 과정에서 제외할 필드 설정, null로 값이 들어가게 됨), volatile
직렬화 : JVM 메모리에 있는 객체를 바이트 스트림으로 변환하여 저장하거나, 네트워크 상에서 전송할 수 있는 형태로 변환하는 과정을 말한다.
jpa에서 entity의 경우 JPA 프로바이더(Hibernate 등)가 직렬화를 대체하는 자체 메커니즘을 사용하기 때문에 꼭 implements Serializable 안 붙여줘도 된다.
[Class, Constructor, Method, Field].getModifier
- 제어자를 반환해주는 메소드이다.
- 반환 타입은 int이다.
- 이 때 제어자가 비트맵으로 인코딩되어 각 제어자는 하나의 단일 비트로 표현된다. 예를 들어 public의 경우 1의 값으로 0000 ... 0001의 값이다.
- 또한 Modifier 클래스 안에 상수로 각각에 대한 제어자가 선언되어 있다.
- 이를 통해 비트 단위의 연산을 통해 제어자를 특정할 수 있다.
- 혹은 Modifier 클래스 안에 isPublic(int modifier), isFinal(..), isStatic(..)와 같은 static 메소드가 존재하기에 이를 통해서도 제어자를 특정할 수 있다.
Example
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
// printClassModifiers(Class.forName("modifiers.auction.Bid$Builder$BidImpl"));
// printMethodsModifiers(Auction.class.getDeclaredMethods());
printFieldsModifiers(Auction.class.getDeclaredFields());
}
public static void printFieldsModifiers(Field[] fields) {
for (Field field : fields) {
int modifier = field.getModifiers();
System.out.printf("Field \"%s\" access modifier is %s\n",
field.getName(),
getAccessModifierName(modifier));
if (Modifier.isVolatile(modifier)) {
System.out.println("The field is volatile");
}
if (Modifier.isTransient(modifier)) {
System.out.println("The field is transient and will not be serialized");
}
if (Modifier.isFinal(modifier)) {
System.out.println("The field is final");
}
System.out.println();
}
}
public static void printMethodsModifiers(Method[] methods) {
for (Method method : methods) {
int modifier = method.getModifiers();
System.out.printf("%s() access modifier is %s\n",
method.getName(),
getAccessModifierName(modifier));
if (Modifier.isSynchronized(modifier)) {
System.out.println("The method is synchronized");
} else {
System.out.println("The method is not synchronized");
}
System.out.println();
}
}
public static void printClassModifiers(Class<?> clazz) {
int modifier = clazz.getModifiers();
System.out.printf("Class %s access modifier is %s\n",
clazz.getSimpleName(),
getAccessModifierName(modifier));
if (Modifier.isAbstract(modifier)) {
System.out.printf("The class is abstract\n");
}
if (Modifier.isInterface(modifier)) {
System.out.printf("The class is an interface\n");
}
if (Modifier.isStatic(modifier)) {
System.out.printf("The class is static\n");
}
}
private static String getAccessModifierName(int modifier) {
if (Modifier.isPublic(modifier)) {
return "public";
} else if (Modifier.isProtected(modifier)) {
return "protected";
} else if (Modifier.isPrivate(modifier)) {
return "private";
} else {
return "package-private";
}
}
public static void runAuction() {
Auction auction = new Auction();
auction.startAuction();
Bid bid1 = Bid.builder()
.setBidderName("Company1")
.setPrice(10)
.build();
auction.addBid(bid1);
Bid bid2 = Bid.builder()
.setBidderName("Company2")
.setPrice(12)
.build();
auction.addBid(bid2);
auction.stopAuction();
System.out.println(auction.getAllBids());
System.out.println("Highest bid :" + auction.getHighestBid().get());
}
}
'JAVA > Reflection' 카테고리의 다른 글
애너테이션 with Reflection 2 (0) | 2024.12.01 |
---|---|
애너테이션 with Reflection 1 (0) | 2024.12.01 |
메서드 탐색과 호출 with Reflection (0) | 2024.11.26 |
필드 조정 및 배열 생성 with Reflection (0) | 2024.11.25 |
필드 검사와 배열 검사 with Reflection (0) | 2024.11.24 |