• Home
  • About
    • Young's Github Pages photo

      一日不作一日不食

    • About
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

Java 정리 10

26 Nov 2018

Reading time ~5 minutes

Java 정리 10 - Constructor, this, String


Constructor (생성자)

  • 객체가 생성될 때 가지고 있어야 할 기본 값 (객체 초기화값)이나 수행될 코드를 정의하는 method 일종
  • 반환형이 없다.
  • Overload 지원(객체 생성을 다양하게 할 수 있다)
  • 클래스명과 동일하게 만든다
  • 개발자가 생성자를 하나도 정의하지 않으면 Compiler가 매개변수 없는 기본생성자(Default Constructor)를 생성해준다.
    • 접근지정자는 class의 접근지정자를 따라간다.
  • 객체 생성할때만 호출된다.
    • method 호출하듯이 직접 호출할 수 없다.
    • this를 사용하면 내 클래스의 다른 생성자를 호출할 수 있다.
접근지정자 생성자명(parameter...) {
    
}

// 생성자의 접근지정자
public    - 클래스 외부에서 객체 생성가능
protected - 동일 패키지 다른 클래스에서만 객체생성가능
            패키지가 다르다면 자식클래스만 객체생성가능
private   - 클래스안에서만 객체 생성가능(singleton pattern 적용)
default   - 동일 패키지 다른 클래스에서만 객체생성가능
            패키지가 다르다면 객체생성불가능
public class Marker {

    ...
    public Marker() {
        color = "검은색";
        cap = 1;
        body = 1;
    }
    public Marker(String color, int cap, int body) {
        this.color = color;
        this.cap = cap;
        this.body = body;
    }
    ...
}
// 클래스명 객체명 = new 생성자();
Marker m = new Marker();             // 기본생성자 - 검은색 마카펜

m.setColor("빨간색");                // 검은색->빨간색 심교체..

// 그냥 첨부터 빨간펜을 만들자!
Marker r = new Marker("빨간색",1,1); 

// setter를 안불러도 되므로 코드가 짧아짐
// => 생성자 오버로딩(다형성)
public class TestConstructor {
    
     public TestConstructor() {
           System.out.println("기본 생성자");
     }
     
     public TestConstructor(int i) {
           System.out.println("인자있는 생성자 : "+i);
     }
     
     public void test() {
           System.out.println("test method");
           temp();
           // 생성자는 메소드 호출하듯 호출할 수 없다.
           // TestConstructor();
     }
     
     public void temp() {
           System.out.println("----temp method");
     }
     
     public static void main(String[] args) {
           // Overloading된 생성자를 사용하여 객체화를  다양하게 할 수 있음
           TestConstructor tc = new TestConstructor(); // 기본  생성자
           System.out.println(tc);
           
           TestConstructor tc1 = new TestConstructor(2); //  인자있는 생성자
           System.out.println(tc1);
           
           tc.test();
     }
}

this

  • 생성자를 호출하거나 heap 주소(생성된 객체의 주소)를 가지는 keyword.
  • method형식과 keyword 형식으로 사용
    • method 형식 - 생성자를 호출
    • keyword 형식 - 생성된 객체의 주소를 사용할 때

this의 method 형식

  • 내 클레스의 Overloading된 생성자를 호출할 때 사용
  • 규칙
    • 생성자의 첫번째 줄에서만 사용가능
    • 재귀호출 불가능
this();                // 기본 생성자 호출
this(인수값, ... );     // 인수있는 생성자 호출
public class Test {

    public Test() {         // 호출순서 2, 4
        this(11);
        ...
    }

    public Test(int i) {    // 호출순서 3
        ...
    }
}

...
// Test 객체를 사용하기위해 다른 클래스에서 객체 생성 시 호출
Test t = new Test();        // 호출순서 1, 5
public class ThisConstructor {
     public ThisConstructor() {
           this(26);
           System.out.println("기본 생성자");
     }
     
     public ThisConstructor(int i) {
           System.out.println("인자있는 생성자 i:"+i);  
           // this는 생성자의 첫번째 줄에서만 사용가능
           // this(); // error!        
     }
     
     public static void main(String[] args) {

           // 객체를 저장해서 사용할 일이 없을 때 이렇게 사용
           new ThisConstructor();
     }
}

01

public class Marker {
     ...
     public Marker() {
           // 인자 있는 생성자를 호출하여 값 설정(코드량 감소)
           this("검은색",1,1);

           // color = "검은색";
           // body = 1;
           // cap = 1;
     }
     
     public Marker(String color, int cap, int body) {
           this.color = color;
           this.body = body;
           this.cap = cap;
     }
     ...

call by value

  • method의 매개변수를 기본형 데이터형으로 정의하면 값이 복사되어 넘어간다.
  • 값 전달
public class Test {

    // swap 메소드 호출 시 i,j 값은 복사되어 들어간다
  public void swap(int i, int j) {
    int temp = 0;
    temp = i;
    i = j;
    j = temp;
  }

  public static void main(String[] args) {
  
    int i=100, j=300;
    System.out.println(i+" "+j); // 100 300

    Test t = new Test();
    t.swap(i,j);

    System.out.println(i+" "+j); // 100 300
  }
}

call by reference

  • method의 매개변수를 참조형 데이터형으로 정의하면 하나의 주소가 그대로 전달된다.
  • 주소 전달
public class Test2 {
  int i;
  int j;
  
  public void swap(Test2 t) {
    int temp = 0;
    temp = t.i;
    t.i = t.j;
    t.j = temp;
  }
  
  public static void main(String[] args) {
    
    Test2 t2 = new Test2();
    
    t2.i = 100;
    t2.j = 300;
    
    System.out.println(t2.i+" "+t2.j); // 100 300
    t2.swap(t2);
    System.out.println(t2.i+" "+t2.j); // 300 100
  }
}

this의 keyword 형식

  • 생성된 객체의 주소를 저장한 keyword
  • static 영역안에서는 사용할 수 없다
this.변수명;
this.method명();
public class ThisKeyword {
  int i;
  
  // 인스턴스변수와 파라미터 변수가 같기 때문에 객체를 넘겨받아 구분하는 것
  public void useInstance(int i, ThisKeyword t) {
    // 파라미터 변수의 값을 인스턴스변수에 할당하겠습니다.
    // == stack의 값을 heap의 값으로 올리겠습니다.
    System.out.println("전달받은 객체 t:"+t);
    t.i = i;
  }

  // Call By Reference로 객체를 매번 넘기는 걸 안하기 위해서 this를 사용
  public void useThis(int i) {
    // this는 메소드를 호출하는 객체의 주소로 바뀐다.
    // 매개변수로 객체를 받을 필요가 없다.
    this.i = i;
    System.out.println("메소드를 호출한 객체의 주소 :  "+this);
  }
  
  public static void test() {
    // static method 안에서는 this 키워드를 사용할 수  없다.
    // this.i = 10; // error!
    System.out.println("static method");
  }
  
  public static void main(String[] args) {
        
    ThisKeyword tk = new ThisKeyword();
    System.out.println("생성된 객체 tk:"+tk);
    
    tk.useInstance(10, tk);
    System.out.println("전달한 객체의 인스턴스변수의  값 "+tk.i);
    
    System.out.println("===========================================");
    
    tk.useThis(3300);
    System.out.println("this를 사용하여 변경한  인스턴스변수의 값 "+tk.i);
    
    ThisKeyword.test();
  }
}

문자열

  • 문자열 != String
  • “로 묶여있는 여러 글자들
  • 문자열은 “문자열 저장소”라는 literal에 생성
    • 같은 문자열은 하나만 생성되고 그 주소를 사용하게된다.
  • 문자열을 저장하고 사용하기 위한 class로 java.lang패키지에 String 제공
    • String class에서 제공하는 모든 method를 사용가능

String

  • 참조형 데이터형
  • 문자열 저장소의 주소를 저장할 수 있는 데이터형
  • 기본형 형식, 참조형 형식 두가지로 사용가능
  • 객체에 == 을 사용하면 주소가 같은지 비교
    • 기본형 형식으로 만들면 literal를 참조하여 같은 문자열인지 비교할 수 있다.
    • 참조형 형식으로 만들면 heap을 참조하여 같은 문자열인지 비교할 수 없다.
  • equals method를 사용하면 객체 내 주소를 비교하는 기능을 수행
    • 기본형이나 참조형 형식 모두 같은지에 대한 비교를 할 수 있다.
// 기본형 형식 (new를 사용하지 않음)
String name = "young";

// 참조형 형식 (new를 사용)
String name = new String("young");
public class TestString {
  public static void main(String[] args) {

    // 기본형 형식의 사용
    String str1 = "ABC";
    
    // 기본형 형식으로 선언한 문자열은 문자열  저장소의 주소를 저장하기
    // 때문에 == 비교로 같은지 비교수행할 수 있다.
    if (str1 == "ABC") {
      System.out.println("기본형 == 같음");
    } else {
      System.out.println("기본형 == 다름");
    }
    
    // 참조형 형식의 사용
    String str2 = new String("ABC");

    // 참조형 형식으로 사용하면 변수는 heap주소를  저장하고
    // heap에 만들어진 객체가 문자열 저장소의  주소를 저장한다.
    if (str2 == "ABC") {
      System.out.println("참조형 == 같음");
    } else {
      System.out.println("참조형 == 다름");
    }
    
    System.out.println("----------------------");
    
    if (str1.equals("ABC")) {
      System.out.println("기본형 equals 비교  같음.");
    } else {
      System.out.println("기본형 equals 비교  다름.");
    }
    
    if (str2.equals("ABC")) {
      System.out.println("참조형 equals 비교  같음.");
    } else {
      System.out.println("참조형 equals 비교  다름.");
    }
  }
}

02


숙제풀이

  • 지난 시간에 만든 라면 클래스에 기본 생성자와 인자있는 생성자를 정의한 후 해당 생성자를 사용하여 객체를 생성하고 사용해보세요.

Ramen class UseRamen class



Java