Java Study #7

allzeroyou·2022년 2월 3일
0

Java

목록 보기
7/14

1. 필드

클래스의 내부 구성 요소 중 첫 번째

1-1. 필드 vs 지역 변수

필드는 클래스에 포함된 변수로 객체의 속성값을 지정할 수 있다.
지역변수는 메서드에 포함된 변수로 중괄호 안에서만 유효한 변수이다.

이때, 필드는 클래스의 중괄호 안에 선언된 변수이고 지역변수는 메서드의 중괄호 안에 선언된 변수이다.

둘의 큰 차이점은 생성되는 메모리 위치로 필드는 힙 메모리의 객체 내부, 지역변수는 스택 메모리에 생성된다.
힙 메모리의 객체 안에 저장되는 필드는 객체가 사라지지 않는 한 절대 삭제되지 않고, 스택 메모리에 저장되는 지역변수는 자바 가상 머신이 때가 되면 자동 삭제한다.

그렇다면 언제 스택 메모리의 변수가 자동 삭제될까?
자신이 선언된 메서드의 중괄호가 닫혀 메서드 종료시!

클래스 A에는 필드 m,n / 메서드 work1(), work2()가 있다. work1() 메서드 안에서는 지역변수 k를 선언해 사용, work2() 에서는 지역변수 i, j를 사용했다.
그 아래 코드는 클래스 A의 인스턴스를 선언하고 내부의 필드와 메서드를 사용했다.
먼저 클래스 A로 인스턴스를 생성, 참조변수명은 a로 선언
참조변수 a와 포인트 연산자(.)을 통해 필드 m과 n의 값 출력
work1()메서드를 호출한 후 work1() 메서드 안에서 work2(3)에서 work2()메서드를 호출해서 3을 넘겨 work2() 메서드에서 i가 3이 되도록 했다. 그 다음 j와 더해 7이 출력되었다.

1-2. 필드 vs 지역 변수 2

필드는 직접 초기화 하지 않아도 강제 초기화됨
지역변수는 직접 초기화하지 않으면 저장 공간이 빈 공간 그대로 있어서 값을 출력하고자 할 때 오류 발생.
각 위치하는 메모리 영역의 특징임.
필드는 힙 메모리에 위치하는데, 힙 메모리는 빈 공간 저장이 불가해 강제 초기화.
지역변수는 스택 메모리에 저장되는데, 스택 메모리는 강제로 초기화되지 않음.

강제 초기화 값은 필드의 자료형에 따라 다름.

  • 기본 자료형일 때
    • 정수형은 0
    • boolean 자료형은 false.
    • 실수형은 0.0
  • 참조 자료형일 때
    어느 위치도 가르키고 있지 않음을 나타내는 null

2. 메서드

클래스의 내부 구성 요소 중 두 번째

2-1. 메서드 정의

클래스의 기능
사람 클래스라면 먹기, 잠자기, 공부하기
자동차 클래스라면 전진하기, 후진하기, 우회전하기 등이 메서드로 구성될 것.

메서드의 정의

자바제어자 리턴(반환)타입 메서드명(입력매개변수)
{
메서드 내용
}

리턴 타입은 메서드 종료 이후 반환되는 값의 자료형의미!

2-2. 여러 리턴 타입의 메서드

  1. 리턴 타입 void, 입력매개변수 없음
    메서드가 반환하는 값이 없고 return 없음
void print(){
	System.out.println("안녕");
}
  1. 리턴 타입 있음, 입력매개변수 없음
    메서드 호출 이후 값이 3으로 변환, return 있음
int data(){
	return 3;	
}

3.리턴 타입 있음, 입력매개변수 있음
int형과 double형 데이터를 받아 double형 리턴

double sum(int a, double b){
	return a+b;
}

2-3. 메서드 호출하기

클래스 외부에서 메서드 호출하기

메서드 또한 클래스의 멤버임.
클래스 외부에서 메서드를 사용하려면 먼저 인스턴스를 생성해야. 그 다음 인스턴스의 위치를 저장하고 있는 참조변수를 이용해 메소드를 호출해야 함.

리턴 타입이 void인 메서드의 경우 리턴되는 값이 없어 그대로 메서드만 호출(a.print())
그러나 리턴값이 있는 메서드의 경우 일반적으로 리턴되는 값을 저장할 수 있는 변수를 선언해 대입(int k = a.data())
입력매개변수가 있는 함수를 호출할 때는 해당 자료형 값을 넘겨줘야.
double sum(int a, double b)메서드에는 2개의 입력매개변수가 있으며, 첫번째는 int, 두번째는 double형을 입력값을 받음.
이를 호출하려면 a.sum(3, 1.2)와 같이 자료형에 맞는 2개의 값을 넘겨줘야.
sum()메서드의 지역변수인 a 값에는 3, b 값에는 1.2가 입력되어 메서드가 종료할 때 4.2.

클래스 내부에서 메서드 호출하기

클래스 내부에 있는 메서드끼리는 인스턴스를 생성하지 않고 서로 호출가능.(같은 멤버이기에)
같은 멤버끼리는 클래스 내부에서 얼마든지 인스턴스를 생성하지 않고 서로 호출 가능

입력매개변수가 배열인 메서드 호출하기

  1. 호출할 때 배열 데이터 입력 방법

  1. 기본 자료형 입력배개변수와 참조 자료형 입력매개변수 차이
  • 배열과 같은 참조 자료형이 입력매개변수로 넘겨질 때 실제 객체가 전달되는 것이 아니라 객체의 위칫값(참조값)이 전달됨. 기본 자료형이 입력매개변수로 넘겨질 때와 다른 동작 수행

  • twice(3) 호출로 넘겨진 3은 twice() 메서드 지역변수 a에 복사되고 a 값을 두번 곱한 값을 a로 저장한 후 리턴한다.
    즉, result 값은 6이다.
    main()메서드의 a 값을 twice()메서드의 입력값으로 넘겨주었다. twice()메서드에서는 int a(twice()메서드의 지역변수)=a(main()메서드의지역 변수)를 가장 먼저 실행.
    등호(=)는 스택메모리를 복사해라!라는 뜻
    main()메서드의 지역 변수 a의 스택 메모리 값이 twice()메모리의 지역 변수 a로 복사.
    이후 twice() 메소드는 자신의 a값을 2배로 곱한 후 a에 대입. twice()메서드의 a 값에는 6 저장.
    이때 twice()메서드 호출 끝나고 main()메서드로 돌아와도 a 값은 3임.
    twice()메서드에서는 한번도 main()메서드의 값을 건드린 적 없기 때문.
    twice()메서드 실행 후 main()메서드로 돌아왔을 때는 twice() 프레임 삭제된 후 임!
    기본 자료형을 입력매개변수로 전달 => 전달받은 메서드는 값을 복사해 사용
  • 입력매개변수로 넘겨진 변수의 스택 메모리 값이 복사돼 사용하는 건 동일하지만 참조 자료형은 스택 메모리에 인스턴스의 참조값(위치값)을 저장하고 있으므로 실제 객체가 아닌 참조값이 전달돼 복사.
    그러다 보니 호출한 메서드와 호출된 메서드에서 모두 동일한 객체를 바라보고 있음. 따라서 호출된 메서드에서 객체 값을 변경후 호출된 메서드로 돌아오면 값 변경됨.

오버로딩된 메서드

메서드 시그니처
메서드명입력매개변수의 자료형
시그니처에서 유추할 수 있듯이 메서드를 구분하는 기준 역할
자바가상머신은 메서드 시그니처가 다르면 메서드명이 동일해도 다른 메서드로 인식
(호출과저에서 리턴 타입을 사용하지 않으므로 리턴 타입으로 메서드 구분 x, 시그니처에 포함 x)

메서드 오버로딩은 이러한 특징을 이용해, 입력매개변수의 개수나 자료형이 다른 여러 개의 동일한 이름을 지닌 메서드를 같은 공간에 정의하는 것을 말함.
(이름이 같지만 확장자명이 다른 abc.jpg, abc.bmp, abc.png를 한 폴더에 저장할 수 있는 것과 같음)

가변 길이 배열 입력매개변수 메서드

메서드 시그니처는 입력매개변수의 개수 또는 입력매개변수의 자료형에 따라 구분된다.
어떤 메서드가 입력매개변수로 0~10개 사이의 int 자료형 값을 받는다고 가정.
몇 개의 입력이 들어올지 모르므로 11개의 메서드를 모두 오버로딩해야.
이를 간단하게 할 수 있는 방법이 가변길이 배열 입력매개변수.
개수가 정해지지 않은 가변 길이의 입력을 받는 입력매개변수로 입려된 값들은 배열로 저장.
배열의 크기는 함수가 호출될 때 전달된 입력값의 개수로 정해짐.

method1(int ... values)는 개수와 상관없이 정수 입력 받을 수 있음
method2(String ... values)는 개수와 상관없이 문자열을 입력 받을 수 있음.
가변 길이 배열 입력매개변수를 이용해 단 1개의 메서드로 모든 메서드 호출에 대응가능.


3. 생성자

생성자는 인스턴스를 생성하는 역할을 지닌 클래스의 내부 구성 요소

생성자 특징

  1. 반드시 클래스명과 동일한 이름으로 짓기
  2. 메소드와 비슷한 구조 but 리턴 타입 존재 x
class A{
	A() {
    	//...
    }
}

기본 생성자 자동 추가

A a = new A() 와 같이 생성자를 호출해 인스턴스를 만들어 왔지만 생성자를 만든 기억은 없다.
생성자를 포함하지 않는 클래스에게 컴파일러에게 기본 생성자를 추가해주었기 때문.
클래스와 인스턴스를 붕어빵 틀과 붕어빵이라고 했다.
생성자는 붕어빵을 찍는 기능 정도로 생각하자.
생성자가 없는 클래스는 붕어빵을 만들 수 없는 붕어빵 틀이다.
그래서 컴파일러는 생성자가 없는 클래스를 만들면 적어도 1개의 생성자가 필요하므로 입력 매개벼수가 없는 기본 생성자를 추가해줌.
생성자가 호출되는 것만으로도 인스턴스가 내부적으로 생성됨.

생성자와 객체의 생성 방법

생성자의 모양에 따라 객체를 생성하는 방법 결정됨

클래스 A에서 서로 다른 내용의 생성자 3개가 오버로딩돼 있다면 클래스 A로 객체를 만드는 3가지 방법 존재

4. this 키워드와 this()메서드

4-1. 내부 객체 참조 변수명인 this 키워드

클래스 내부에서도 인스턴스 안의 멤버를 사용해옴.
'참조 변수명.멤버명' 형태를 사용해 옴
모든 메서드에는 자신이 포함된 클래스의 인스턴스를 가리키는 this 라는 참조 변수가 있음

모든 멤버는 객체 속에 존재하므로 int m = 3이라는 필드를 클래스 내부에서 출력하고자 할 때 System.out.println(this.m)으로 작성해야 한다.
그러나 this.를 생략하면 컴파일러가 자동으로 추가해줌.

init()메서드에서 넘겨받은 a, b값을 필드 m과 n의 값에 대입. 또한 work()메서드에서는 init()메서드를 호출했다. 이렇게 클래스 내부에서 멤버인 필드와 메서드르 호출 할 때는 this를 이용해 표현되어야 하며 생략했을 때 자동으로 추가된다.

그러나 this를 명시적으로 표현해야 할 때도 있는데, 지역변수와 필드명이 동일할 때이다. 이름이 달랐따면 필드와 지역변수를 명시적으로 구분할 필요가 없었겠지만 자바에서 제공하는 대부분의 API에는 메서드의 지역변수명이 필드명과 동일하게 구성돼있다.

4-1. 클래스 내 다른 생성자를 호출하는 this() 메소드

this 키워드와 매우 비슷하게 생겼지만 의미는 전혀 다르다.
자신이 속한 클래스 내부의 다른 생성자를 호출한다.

  • this()메서드를 사용할 때의 규칙
  1. 생성자의 내부에서만 사용
  2. 생성자의 첫 줄에 위치

클래스 A에는 2개의 생성자 => 객체 생성 2가지 방법
첫번째 생성자는 기본 생성자로 내부에는 1개의 출력문 존재 그 결과 "첫번째 생성자" 문자열 출력
두번째 생성자는 객체를 생성하면 생성과정에서 두번 째 생성자가 실행된다. 첫번째 명령은 this()이고 이는 자신의 또 다른 생성자인 A()를 호출하라는 말.
따라서 먼저 첫번째 생성자가 호출된 후 나머지 코드 실행 => "첫번째 생성자"와 "두번째 생성자" 모두 출력




📕 참고문헌) Do it! 자바 완전 정복!

profile
모든 건 zero 부터, 차근차근 헛둘헛둘

0개의 댓글