개요
Java 이용하면서 패키지 내부의 자원을 찾을 때 classpath를 자주 이용하곤 했는데, Class::getResource와 ClassLoader::getResource의 차이가 무엇인지 몰랐음
그러던 와중에 상대 경로와 함께 ClassLoader를 이용하니 NPE가 발생하는 문제를 겪었고, 두 개념의 정리가 필요함을 느낌
차이
foo.bar 패키지로 구성되어 있고, Baz라는 클래스가 있다고 가정
동일 패키지 경로의 xyz.txt를 읽으려는 상황
package foo.bar;
import java.net.URL;
public class Baz {
public static void main(String[] args) {
URL resource1 = Baz.class.getResource("/foo/bar/xyz.txt");
URL resource2 = Baz.class.getResource("xyz.txt");
resource1EqualsResource2(resource1, resource2);
URL resource3 = Baz.class.getClassLoader().getResource("xyz.txt");
classLoaderDoesNotUseRelative(resource3);
URL resource4 = Baz.class.getClassLoader().getResource("foo/bar/xyz.txt");
classLoaderDoesUseAbsolute(resource4, resource1);
URL resource5 = Baz.class.getClassLoader().getResource("/foo/bar/xyz.txt");
classLoaderStartsWithSlashDoesNotWorkExpected(resource5);
}
private static void resource1EqualsResource2(URL resource1, URL resource2) {
System.out.println(resource1.equals(resource2));
}
private static void classLoaderDoesNotUseRelative(URL resource) {
System.out.println(resource == null);
}
private static void classLoaderDoesUseAbsolute(URL resource1, URL resource2) {
System.out.println(resource1.equals(resource2));
}
private static void classLoaderStartsWithSlashDoesNotWorkExpected(URL resource) {
System.out.println(resource == null);
}
}
Java
복사
Class::getResource를 사용하는 경우
foo.bar
.Baz.class
.getResource("xyz.txt");
foo.bar
.Baz.class
.getResource("/foo/bar/xyz.txt");
Java
복사
ClassLoader::getResource를 사용하는 경우
foo.bar
.Baz.class
.getClassLoader()
.getResource("foo/bar/xyz.txt")
Java
복사
정리
두 구문은 같은 결과를 반환하는데, Class::getResource는 클래스를 기준으로 상대 경로를 처리할 수 있으며, ClassLoader::getResource는 입력된 경로를 절대 경로로 처리
** Class::getResource는 절대 경로도 가능
** ClassLoader::getResource는 입력된 경로를 절대로 처리하기에 “/”로 시작하면 경로를 찾지 못함
결론
어떤 것을 이용해야한다는 자료는 찾지 못하였는데, 표현력은 Class::getResource가 더 풍부한 것 같고 상대적으로 예외도 덜 발생할 것으로 보임
또한 ClassLoader::getResource가 절대 경로를 이용함에도 “/”를 뺀 이후로 절대적으로 입력해야하는 사실이 익숙하지 않기에, 가급적으로 Class::getResource를 이용해야겠음
Class::getResource 쓰자