데이터 타입 | 기본값 |
---|---|
byte | 0 |
char | \u0000 (공백) |
short | 0 |
int | 0 |
long | 0L |
float | 0.0F |
double | 0.0 |
boolean | false |
배열 | null |
클래스 | null |
인터페이스 | null |
필드를 사용한다
라는 것은 필드의 값을 변경하거나 읽는 것을 의미
- 외부 접근
- 객체를 생성하면 참조변수를 이용하여 외부에서 객체 내부의 필드에 접근하여 사용 가능
- 이때 내부 필드에 접근 하는 방법은
.
(도트 연산자)를 사용Car car = new Car(); car.color = "blue";
- 내부 접근
- 객체 내부 메소드에서도 내부 필드에 접근 가능
double brakePedal() { // 객체의 필드 speed를 호출해서 사용 speed = 0; return speed; }
- 객체의 행위를 뜻하며 객체 간의 협력을 위해 사용
접근제어자 리턴타입 메소드명(매개변수, ...) { 실행문; return 리턴값; }
- 리턴값이 없는 경우에는 리턴타입에
void
를 설정하며, 리턴값이 없기 때문에 return 구문도 불필요double gasPedal(double kmh, char type) { speed = kmh; return speed; } // 매개변수가 double, char이기 때문에 순서에 맞게 입력 gasPedal(100, 'D');
- 매개변수는 메소드를 실행하기 위해 필요한 값을 받기 위해 사용되는 변수로서 순서와 타입을 맞춰서 입력해야함
- 필요하지 않다면 생략도 가능
- 가변 길이의 매개변수도 선언 가능
void carSpeeds(double ... speeds) { for (double v : speeds) { System.out.println("v = " + v); } } carSpeeds(100, 80); carSpeeds(120, 40, 150);
메소드를 호출한다
라는 의미는 메소드의 블록 내부에 작성된 코드를 실행한다는 의미
- 외부 접근
- 객체를 생성하면 참조변수를 이용하여 외부에서 객체 내부의 메소드에 접근하여 사용 가능
- 이때 내부 메소드에 접근하는 방법은
.
(도트 연산자)를 사용- 또한, 메소드가 매개변수를 가지고 있다면 순서와 타입에 맞게 입력 필요
Car car = new Car(); car.breakPedal(); car.gasPedal(100, 'D');
- 내부 접근
- 객체 내부 메소드에서도 내부 메소드에 접근 가능
double gasPedal(double kmh, char type) { // 내부 메소드에 접근 changeGear(type); speed = kmh; return speed; }
- 리턴값 저장
- 메소드에 리턴값이 있다면 변수를 사용하여 저장 가능
double speed = car.gasPedal(100, 'D');
오버로딩 은 메소드가 하나의 기능만을 구현하는 것이 아닌, 여러 기능을 구현하도록 하는 기능
즉, 이미 존재하는 메소드명이더라도 매개변수의 갯수 또는 타입 또는 순서가 다르면 동일한 메소드명을 사용해서 메소드를 정의할 수 있음
- 메소드명 하나로 상황에 따른 동작을 정의할 수 있음
// 자주 사용하는 println()의 메소드 오버로딩 public class PrintStream extends FilterOutputStream implements Appendable, Closeable { ... public void println() { newLine(); } public void println(boolean x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { synchronized (this) { print(x); newLine(); } } } public void println(char x) { if (getClass() == PrintStream.class) { writeln(String.valueOf(x)); } else { synchronized (this) { print(x); newLine(); } } } ... }
- 기본형 매개변수 : 값을 복사하여 처리하기 때문에 아무런 영향이 없음 (call by value)
- 참조형 매개변수 : 값의 주소를 참조하기 때문에 직접 영향을 줌 (call by reference)
// 기본형 매개변수 class Data { int x; } class para { public static void main(String[] args) { Data d = new Data(); d.x = 10; System.out.println("main() : x = " + d.x); // x = 10 change(d.x); // x = 1000 System.out.println("After change(d.x)"); System.out.println("main() : x = " + d.x); // x = 10 } static void change(int x) { x = 1000; System.out.println("change() : x = " + x); } }
// 참조형 매개변수 class Data { int x; } class para { public static void main(String[] args) { Data d = new Data(); d.x = 10; System.out.println("main() : x = " + d.x); // x = 10 change(d); // x = 1000 System.out.println("After change(d)"); System.out.println("main() : x = " + d.x); // x = 1000 } static void change(Data d) { d.x = 1000; System.out.println("change() : x = " + d.x); } }
- 멤버 = 필드 + 메소드
- 인스턴스 멤버 = 인스턴스 필드 + 인스턴스 메소드
- 클래스 멤버 = 클래스 필드 + 클래스 메소드
- 필드와 메소드는 선언하는 방법에 따라서 인스턴스 멤버와 클래스 멤버로 구분
- 인스턴스 멤버는 객체 생성 후에 사용할 수 있고, 클래스 멤버는 객체 생성 없이도 사용 가능
- 인스턴스 멤버
- 객체를 생성해야 사용할 수 있음
- 인스턴스 필드는 각각의 인스턴스마다 고유하게 값을 가질 수 있음
- 하지만 객체가 인스턴스화 할 때마다 인스턴스 메소드는 매번 생성되지 않음
- 매번 생성하게 되면 중복으로 인한 메모리 효율이 매우 떨어지기 때문에 메소드 영역에 두고서 모든 인스턴스들이 공유해서 사용하게 됨
- 대신 인스턴스를 통해서만 메소드가 사용될 수 있도록 제한을 걸어둠
- 클래스 멤버
- Java의 클래스 로더에 의해 메소드 영역에 저장되고 사용됨
- 클래스 멤버는 메소드 영역의 클래스와 같은 위치에 고정적으로 위치하고 있기 때문에 객체의 생성 없이 바로 사용 가능
- 필드와 메소드를 클래스 멤버로 만들기 위해서는 static 키워드를 사용
- 공용적인 데이터를 저장하는 필드를 클래스 멤버로 선언하는 것이 좋음
- 인스턴스 필드를 사용하지 않고 실행되는 메소드라면, static 키워드를 사용하여 클래스 메소드로 선언하는 것이 좋음
⚠️ 주의할 점
- 클래스 멤버로 선언된 메소드는 인스턴스 멤버를 사용할 수 없음
- 반대로 인스턴스 멤버로 선언된 메소드는 클래스 멤버를 사용할 수 있음
- 클래스 멤버는 객체 생성 없이 바로 사용 가능하기 때문에 객체가 생성되어야 존재할 수 있는 인스턴스 멤버를 사용할 수 없음
- 메소드 내부에 선언한 변수
- 메소드가 실행될 때마다 독립적인 값을 저장하고 관리
- 지역 변수는 메소드 내부에서 정의될 때 생성되어 메소드가 종료될 때 소멸
public class Main { public static void main(String[] args) { Main main = new Main(); // 메소드 호출 : main.getClass() System.out.println("main.getClass() = " + main.getNumber()); // 2 System.out.println("main.getClass() = " + main.getNumber()); // 2 System.out.println("main.getClass() = " + main.getNumber()); // 2 } public int getNumber() { int number = 1; // 지역 변수 number += 1; return number; } }
- final 필드는 초기값이 저장되면 프로그램이 실행하는 도중에는 수정할 수 없음
- final 필드는 반드시 초기값 지정이 필요
final String company = "GENESIS"; ... Car car = new Car(); System.out.println(car.company); car.company = "Benz"; // 에러 발생
- final 앞에
static
을 추가하여 모든 인스턴스가 공유할 수 있는 상수를 선언- 일반적으로 모두 대문자로 작성
static final String COMPANY = "GENESIS"; ... System.out.println(Car.COMPANY); Car.COMPANY = "Benz"; // 에러 발생