# Class

## Class 제어

<mark style="color:blue;">Java Reflection</mark>을 이용하여 클래스 정보 객체를 얻어내고 이를 통해 클래스 제어가 가능하다.

`com.hacademy.refelection3.Member` 클래스를 만들고 예제에서 사용한다.

{% code title="Member.java" %}

```java
package com.hacademy.reflection3;

public class Member {
	private String id;
	private String password;
	private String nickname;
	@Override
	public String toString() {
		return "Member [id=" + id + ", password=" + password + ", nickname=" + nickname + "]";
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getNickname() {
		return nickname;
	}
	public void setNickname(String nickname) {
		this.nickname = nickname;
	}
	public Member() {
		super();
	}
	public Member(String id, String password, String nickname) {
		super();
		this.id = id;
		this.password = password;
		this.nickname = nickname;
	}
}

```

{% endcode %}

### 클래스 정보

특정 클래스에 대한 Class 타입의 객체를 다양한 방법으로 구현할 수 있다.

{% code title="Test01.java" %}

```java
package com.hacademy.reflection3;

public class Test01 {
	public static void main(String[] args) throws ClassNotFoundException {
		Class<? extends Member> a = new Member().getClass();
		Class<Member> b = Member.class;
		Class<?> c = Class.forName("com.hacademy.reflection3.Member");
		
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
	}
}
```

{% endcode %}

위의 코드 중에서 객체 없이 설정한 값에 의해 클래스 정보를 불러올 수 있는 방식은 c이다.

```java
Class<?> c = Class.forName("com.hacademy.reflection3.Member");
```

`Class.forName()` 은 대상 클래스의 정보를 클래스로더(ClassLoader)에 등록한 뒤 반환하는 명령이다. 이 때, 대상의 <mark style="color:red;">static</mark> 정보들은 미리 등록된다.

예를 들면 다음과 같이 처리할 수 있다.

{% code title="Test02.java" %}

```java
package com.hacademy.reflection3;

public class Test02 {
	public static void main(String[] args) {
		if(args.length != 2) 
			throw new IllegalArgumentException("usage : java Test02 [basePackage] [className]");
		
		String basePackage = args[0];
		String className = args[1];
		String fullPath = basePackage+"."+className;
		try {
			Class<?> c = Class.forName(fullPath);
			System.out.println("c = " + c);
		}
		catch(ClassNotFoundException e) {
			System.err.println("잘못된 클래스 경로");
		}
	}
}

```

{% endcode %}

Properties 또는 기타 입출력 방식을 통하여 불러온 정보로도 클래스 정보를 불러올 수 있다.

### 필드 정보

```java
package com.hacademy.reflection3;

import java.lang.reflect.Field;

public class Test03 {
	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> c = Class.forName("com.hacademy.reflection3.Member");
		
		System.out.println("<accessible field list>");
		for(Field field : c.getFields()) {
			System.out.println(field);
		}
		
		System.out.println("<declared all field list>");
		for(Field field : c.getDeclaredFields()) {
			System.out.println(field);
		}
		
	}
}

```

Field는 접근 가능한 필드와 전체 필드를 조회하는 명령이 각각 존재한다.

* `getFields(`) - 상속관계를 포함한 접근 가능한 Field 목록 반환
* `getDeclaredFields()` - 해당 클래스에 명시된 전체 Field 목록 반환

현재 Member 클래스에는 <mark style="color:red;">private field</mark>만 존재하므로 getFields() 로는 결과가 나오지 않고 getDeclaredFields()로만 결과가 나오는 것을 확인할 수 있다.

### 메소드 정보

```java
package com.hacademy.reflection3;

import java.lang.reflect.Method;

public class Test04 {
	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> c = Class.forName("com.hacademy.reflection3.Member");
		
		System.out.println("<accessible method list>");
		for(Method method : c.getMethods()) {
			System.out.println(method);
		}
		
		System.out.println("<declared method list>");
		for(Method method : c.getDeclaredMethods()) {
			System.out.println(method);
		}
		
	}
}

```

메소드 정보를 불러오고 싶은 경우 접근 가능한 메소드와 클래스 선언 메소드 전체를 불러오는 두 가지 방법이 존재한다.

* getMethods() : 접근 가능한(상속 포함) 메소드 목록
* getDeclaredMethods() : 클래스에 명시된 메소드 전체 목록

### 생성자 정보

```java
package com.hacademy.reflection3;

import java.lang.reflect.Constructor;

public class Test05 {
	public static void main(String[] args) throws ClassNotFoundException {
		Class<?> c = Class.forName("com.hacademy.reflection3.Member");
		
		System.out.println("<accessible constructor list>");
		for(Constructor<?> constructor : c.getConstructors()) {
			System.out.println(constructor);
		}
		
		System.out.println("<declared constructor list>");
		for(Constructor<?> constructor : c.getDeclaredConstructors()) {
			System.out.println(constructor);
		}
		
	}
}

```

생성자 정보를 불러오고 싶은 경우 역시 접근 가능한 생성자와 전체 생성자를 조회하는 메소드가 따로 존재한다.

* getConstructors() - 접근 가능한 생성자 목록
* getDeclaredConstructors() - 전체 생성자 목록


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sysout.co.kr/base-language/java/java-advanced/java-reflection/class.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
