Super Coding Addict
Ch10. 자바 기본 클래스 (4) - Class 클래스 본문
* Class 클래스
- 자바의 모든 클래스와 인터페이스는 컴파일 후 class 파일로 생성된다
- class파일에는 객체의 정보(멤버변수, 메서드, 생성자 등)가 포함되어 있다
- Class 클래스는 컴파일된 class파일에서 객체의 정보를 가져올 수 있다
- 동적 로딩할 때 많이 씀
- 로컬에 자료형(모듈)이 없는 경우에도 씀
* Class 클래스 가져오기
1.
String s = new String();
Class c = s.getClass();
--> getClass()메서드는 Object의 메서드
2.
Class c = String.Class;
3. 동적로딩 -- 런타임때 바인딩이 됨 cf. 정적로딩 -- 컴파일타임 때
=> 그때그때 내 필요에 맞게 원하는 라이브러리/클래스를 매칭시킬 수 있다는 장점
=> 오타가 나면 로딩되다가 ClassNotFoundException이 나서 런타임이 죽을 수 있음
Class c = Class.forName("java.lang.String");
--> ""안에 명시된 클래스가 로컬에 있으면 runtime때 불러다가 사용
=> 언제든 변수화해서 바꿀 수 있음
가령, 자바에서 JDBC를 쓸 때 여러 DB라이브러리가 있을 수 있는데 그런 라이브러리들을 모두 static하게 링크해서 컴파일할 순 없으므로 (너무 많아서) 라이브러리들은 install해놓 고 필요할 때 부를 수 있게 끔 함
ex) 오라클 라이브러리의 이름을 넣으면 동적로딩 됨!
- 예제 1) Class클래스 가져오기
package ch10.classEx;
public class StringClassTest {
public static void main(String[] args) throws ClassNotFoundException {
Class c1 = String.class;
String str = new String();
Class c2 = str.getClass();
Class c3 = Class.forName("java.lang.String");
}
}
* reflection 프로그래밍
- Class 클래스로부터 객체의 정보를 가져와 프로그래밍하는 방식
- 로컬에 객체가 없고 자료형을 알 수 없는 경우 유용한 프로그래밍
- java.lang.reflect 패키지에 있는 클래스 활용
- 예제 2) reflection 패키지 활용
package ch10.classEx;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class StringClassTest {
public static void main(String[] args) throws ClassNotFoundException {
Class c3 = Class.forName("java.lang.String");
Constructor[] cons = c3.getConstructors();
for(Constructor con : cons) {
System.out.println(con);
}
System.out.println();
Method[] methods = c3.getMethods();
for(Method method : methods) {
System.out.println(method);
}
}
}
--> java.lang.reflect패키지에 있는 Constructor클래스와 Method클래스를 활용하여 String클래스가 가지고 있는 Constructor와 Method 확인 가능
* forName() 메서드와 동적 로딩
- Class클래스의 static메서드
- 동적 로딩이란?
: 실행 중(런타임)에 데이터 타입을 알고 binding되는 방식
cf. 정적 로딩 : 컴파일 시 데이터 타입이 모두 binding되어 자료형이 로딩되는 것
- 실행 시에 로딩되므로 경우에 따라 다른 클래스가 사용될 수 있어 유용하다
- 컴파일 타임에 체크할 수 없으므로, 해당 문자열에 대한 클래스가 없는 경우 예외(ClassNotFoundException) 발생 가능
- 예제 : Person 클래스 동적로딩
# Perosn 클래스
package ch10.classEx;
public class Person {
private String name;
private int age;
public Person() {};
public Person(String name) {
this.name = name;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return name;
}
}
--> 생성자가 기본생성자를 포함해 3가지가 있는 클래스
# ClassTest 클래스
package ch10.classEx;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ClassTest {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Person person = new Person("James");
System.out.println(person);
Class c1 = Class.forName("ch10.classEx.Person");
Person p1 = (Person)c1.newInstance(); //Default Constructor를 호출
System.out.println(p1);
Class[] parameterTypes = {String.class};
Constructor cons = c1.getConstructor(parameterTypes);
Object[] initargs = {"김유신"};
Person personLee = (Person)cons.newInstance(initargs);
System.out.println(personLee);
}
}
Class c1 = Class.forName("ch10.classEx.Person");
--> Class.forName("ch10.classEx.Person");으로 Person클래스를 동적 로딩
Person p1 = (Person)c1.newInstance(); //Default Constructor를 호출
System.out.println(p1); //결과 : null
--> 가져온 Class로 newInstance()를 하면 기본생성자가 호출되므로 p1을 toString()으로 찍어보면 null이 찍힌다 (아무런 매개변수가 들어가지 않았으므로)
--> newInstance()가 반환하는 객체의 타입이 Object이므로 (Person)으로 다운캐스팅
Class[] parameterTypes = {String.class};
Constructor cons = c1.getConstructor(parameterTypes);
Object[] initargs = {"김유신"};
Person personLee = (Person)cons.newInstance(initargs);
System.out.println(personLee); //결과 : 김유신
--> 가져온 Class에서 String클래스의 인자를 파라미터값으로 갖는 생성자를 가져와 cons 변수에 넣음
--> 생성자의 인자로 들어갈 String클래스 변수로 "김유신"을 initargs 변수에 넣음
=> 만약 String클래스의 인자가 여러 개 필요하다면 이 Object배열에 "김유신"뿐만 아니라, 필요한 인자를 더 넣어준다
--> 마찬가지로 newInstnace()가 반환하는 객체 타입이 Object이므로 (Person)으로 다운캐스팅한다
==> 로컬에 있는 클래스라면 쉽게 생성자를 호출할 수 있지만, 로컬에 없는 클래스인 경우 이런식으로 생성자나 메서드를 호출할 수 있기에 쓴다
'JAVA 문법' 카테고리의 다른 글
Ch10. 자바 기본 클래스 (6) - String, Wrapper 클래스 (0) | 2021.03.03 |
---|---|
Ch10. 자바 기본 클래스 (5) - 코딩해보기 (0) | 2021.03.02 |
Ch10. 자바 기본 클래스 (3) - Object 클래스 (0) | 2021.03.01 |
Ch10. 자바 기본 클래스 (2) - Object 클래스 (0) | 2021.03.01 |
Ch10. 자바 기본 클래스 (1) - Object 클래스 (0) | 2021.02.28 |