자바에서 객체를 생성하는 방법
자바에서 객체를 생성하는 방법에는 여러가지가 있다!
1. new keyword 사용
2. new instance 사용
3. clone() 메소드 사용
4. 객체 역질렬화 (Deserialization)
5. Constructor 클래스의 newInstance() 메소드 사용
1. new keyword를 사용해서 객체 만들기
- 매우 쉬운 방법으로 대부분의 사람들이 이 방법을 사용할 것이다. 나도 지금까지 객체를 생성하는 법은 이게 다인줄 알았다. 왜냐하면 이 방법말고 다른 방법은 안배웠기 때문이다. class이름 변수이름 = new class이름(); 이라고 작성하면 된다.
public class Ads {
public static void main(String[] args) {
Ads a = new Ads();
}
}
2. new instance를 사용해서 객체 만들기
- 만약 class의 이름을 알고, 그 class가 기본 생성자를 갖고 있을 때, Class.forName을 사용하여 만들 수 있다. 실제 Class.forName은 객체를 생성하지 않지만, Class class의 newInstance 메소드를 사용해서 만들 수 있다. 이 newInstance() 메소드는 내부에서 Constructor class의 newInstance() 메소드를 사용한다.
* Java 9부턴 Deprecated 처리가 되었다.
package basic;
public class Ads {
public void hi() {
System.out.println("hi");
}
public static void main(String[] args) {
try {
Class cls = Class.forName("basic.Ads");
Ads abc = (Ads)cls.newInstance();
// Deprecated 처리되어 있다. Java 9부터
} catch (ClassNotFoundException cnfe)
// forName 메서드에 매개변수로 들어간 class가 존재하지 않을 경우 발생
{
cnfe.printStackTrace();
System.out.println(cnfe.getMessage());
}
catch(InstantiationException ie)
// newInstance() 메소드는 클래스의 기본 생성자를 호출하기 때문에,
// 기본생성자가 없으면 발생한다.
{
ie.printStackTrace();
}
catch(IllegalAccessException iae)
// 배열 이외의 객체를 생성하거나, 값을 정하거나 불러 올 때 혹은 메소드를 호출할 때
// 현재 실행 중인 메소드가 지정된 클래스에 접근할 수 없는 경우 발생
{
iae.printStackTrace();
}
}
}
3. clone() 메소드를 사용해서 객체 만들기
- 어떤 객체에서든 clone() 메소드를 호출할 때마 JVM은 새로운 객체를 만들어서 이전의 객체의 모든 값을 복사해서 넣는다. 그러나 이 방법은 생성자를 호출하진 않는다. clone() 메소드를 사용하기 위해선 Cloneable 인터페이스를 구현해야하고, 그 안에 선언되어 있는 clone() 메소드의 구현부를 완성시켜야 한다.
package basic;
import java.util.Objects;
public class Ads implements Cloneable {
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
String name;
int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Ads ads = (Ads) o;
return age == ads.age && Objects.equals(name, ads.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public static void main(String[] args){
Ads a = new Ads();
a.name = "Kim";
a.age = 25;
try{
// Object 타입으로 반환되기 때문에 Ads 클래스로 형변환을 해주었다.
Ads b = (Ads)a.clone();
System.out.println(b.name); // Kim
System.out.println(b.age); // 25
System.out.println(b); // basic.Ads@776ec8df, equals, hashcode 오버라이딩 후엔 동일한 값
System.out.println(a); // basic.Ads@4eec7777
System.out.println(a.equals(b)); // equals()와 hashcode를 오버라이딩 해서 true
System.out.println(a==b); // false
} catch(CloneNotSupportedException cne) {
cne.printStackTrace();
}
}
}
4. 역직렬화 해서 객체 만들기 (아직 stream을 잘몰라서 많이 어렵다...)
- 객체를 직렬화하거나 역직렬화 할 때 JVM은 객체를 생성한다. 이때 JVM은 객체를 생성하기 위해 생성자를 사용하지 않는다. 객체 역직렬화를 하기 위해선 Serializable 인터페이스를 구현해야 한다.
* Serialization: ObjectOutputStream class의 writeObject() 메소드를 사용해서 객체를 직렬화할 수 있다. 객체를 output stream으로 보낸다.
* Deserialization: ObjectInputSteam class의 readObject() 메소드를 사용해서 객체를 역직렬화한다. Stream에서 객체를 참조한다.
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
// Serialization
// writeObject() 메소드를 사용해서 직렬화 되었고, file.txt 파일에 쓰여졌다.
class Ads implements Serializable {
private String name;
Ads(String name) {
this.name = name;
}
public static void main(String[] args) {
try{
Ads a = new Ads("Ho");
FileOutputStream f = new FileOutputStream("file.txt");
ObjectOutputStream oos = new ObjectOutputStream(f);
oos.writeObject(a);
oos.close();
f.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
// Desrialization
public class Ads {
public static void main(String[] args) {
try{
Ads a;
FileInputStream f = new FileInputStream("file.txt");
ObjectInputStream oos = new ObjectInputStream(f);
a = (DesrializationExample)oos.readObject();
}
catch (Exception e) {
e.printStackTrace();
}
Systme.out.println(a.name);
}
}
5. Constructor class의 newInstance() 메소드를 사용해서 객체 만들기
- 위에서 언급했던 Class class의 newInstance() 메소드와 유사하다. 그러나 Constructor class의 메소드는 newInstance() 메소드를 사용할 때 매개변수가 있는 생성자나 private 생성자도 호출할 수 있다. Class class의 메소드는 내부적으로 Constructor class의 메소드를 사용한다. Class class의 메소드보다 더 선호된다.
package basic;
import java.lang.reflect.*;
public class Ads {
private String name;
Ads() {}
// 앞에 private을 적어도 문제 없이 실행됨
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
try { Constructor<Ads> a = Ads.class.getDeclaredConstructor();
Ads b = a.newInstance();
b.setName("Hi");
System.out.println(b.name);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
참고 자료
자바 객체를 생성하는 3가지 방법
자바에서 객체를 생성하는 3가지 방법에 대해 알아보겠습니다. 1. 생성자 스타벅스 음료 3잔을 자바 코드로 만들어보겠습니다. StarbucksDrink라는 클래스를 만들고 음료의 종류마다 값을 받을 수 있
www.beemo.co.kr
Different ways to create objects in Java - GeeksforGeeks
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
www.geeksforgeeks.org
https://www.javatpoint.com/how-to-create-object-in-java