public class Test {
private String name;
private String address;
public static Test withName(String name) {
Test test = new Test();
test.name = name;
return test;
}
public static Test withAddress(String address) {
Test test = new Test();
test.address = address;
return test;
}
public static void main(String[] args) {
Test testName = withName("Gyunny");
Test testAddress = withAddress("Address");
}
}
정적 팩토리 메소드는 얼핏보면 생성자와 매우 유사하다. (처음 봤을 때 왜 이렇게 하는지 이해가 안 되기도 했다..)
정적 팩토리 메소드는 생성자와 유사하지만 몇 가지 장점이 있는 객체 생성의 역할을 하는 메소드로 말할 수 있다.
몇가지 이유를 나열해보자
예시 코드를 보면 객체를 생성 할 때 어떤 변수의 초기값을 줄지 지정하고 생성 할 수 있다. (만약 이게 생성자였으면 직접 코드를 까봐야겠지)
그리고 중요한 건 만약 위 예시 코드에서 name만 초기화하는 생성자를 만들었다고 치자. 그렇다면 address를 초기화해서 생성하는 생성자는 만들 수 없다(이미 필드의 갯수가 1개인 생성자를 만들어서). 이럴 경우에도 정적 팩토리 메소드로 해결이 가능하다!
public class Test {
private String name;
private static final Test GOOD_STUDY = new Test();
public static Test Test_goodStudy() {
return GOOD_STUDY;
}
public static void main(String[] args) {
Test test = Test_goodStudy();
}
}
이 코드를 보면 하나의 final 객체를 계속 리턴하는 방식이다. 이와같이 중복된 값이 계속 인스턴스화되지 않게 할 수 있고, 이 방법으로 메모리를 절약할 수 있다.
public interface Type {
static Type getAType() {
return new AType();
}
static Type getBType() {
return new BType();
}
}
class AType implements Type {
}
class BType implements Type {
}
구현하고 있는 클래스를 노출시키지 않을 수 있고, 사용자 입장에서도 반환 된 클래스가 어떤 클래스인지 굳이 찾아보지 않아도 되는 장점도 있습니다.
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, java.io.Serializable
{
public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
EnumSet<E> result = noneOf(elementType);
result.addAll();
return result;
}
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
public static <E extends Enum<E>> EnumSet<E> of(E e1, E e2) {
EnumSet<E> result = noneOf(e1.getDeclaringClass());
result.add(e1);
result.add(e2);
return result;
}
}
해당 코드를 보면 noneOf 메소드를 보면 universe의 길이에 따라 다른 반환 형태를 볼 수 있다. 이와 같이 하위 클래스의 반환 구조를 지정할 수 있다.
from : 하나의 매개 변수를 받아서 객체를 생성
of : 여러개의 매개 변수를 받아서 객체를 생성
getInstance | instance : 인스턴스를 생성. 이전에 반환했던 것과 같을 수 있음.
newInstance | create : 새로운 인스턴스를 생성
get[OtherType] : 다른 타입의 인스턴스를 생성. 이전에 반환했던 것과 같을 수 있음.
new[OtherType] : 다른 타입의 새로운 인스턴스를 생성.