레퍼런스 변수, static
1. 레퍼런스형 변수 vs 기본형 변수
변수의 타입은 크네 레퍼런스형 변수와 기본형 변수로 구분할 수 있다.
1) 레퍼런스형 변수는 객체의 주소를 저장하며 값을 직접 저장하는 것이 아닌 간접적으로 저장하는 변수이다. 기본형변수는 값을 직접 저장하는 변수이다.
2) 레퍼런스형 변수는 타입의 첫문자를 대문자로, 기본형 변수는 소문자로 시작한다.
2. static
static은 '동일한 클래스 타입의 객체들 간의 공유'라는 개념을 의미한다. static은 클래스의 필드와 메소드에 적용되는 개념이다.
- static 필드: 클래스 변수(클래스 영역에 존재하는 변수)
- non-static 필드: 인스턴스 변수(객체(인스턴스) 영역에 존재하는 변수)
- static 메소드: 클래스 메소드(클래스 영역에 존재하는 메소드)
- non-static 메소드: 인스턴스 메소드(객체(인스턴스) 영역에 존재하는 메소드)
예시코드 1
public class Counting {
public static void main(String[] args) {
Student s1 = new Student("호동이", "남");
Student s2 = new Student("나영이", "여");
Student s3 = new Student("민지", "여");
Student[] students = {s1, s2, s3};
for (int i = 0; i < students.length; i++) {
System.out.printf("이름: %s 성별: %s\n", students[i].name, students[i].gender);
}
System.out.printf("학생 수: %d", Student.studentCount);
}
}
class Student {
String name;
String gender;
static int studentCount;
Student(String n, String g) {
name = n;
gender = g;
studentCount++;
}
}
3. 클래스 변수 vs 인스턴스 변수
위의 예시코드에서 인스턴스 변수는 name, gender이다. 그리고 클래스 변수는 studentCount이다. name과 gender는 객체 영역에 존재하기 때문에 각각의 객체 s1, s2, s3가 개별적인 값을 가진다. 하지만 studentCount는 클래스 영역에 존재하기 때문에 각각의 객체들이 하나의 값을 공유한다.
현재 코드에서는 studentCount는 생성자가 한번 호출될 때 마다 1씩 증가한다. 그리고 클래스 변수이기 때문에 +1, +1, +1이 되어서 3 값을 가진다.
그러나 studentCount가 인스턴스 변수일 경우에는 각각의 객체가 개별적인 studentCount를 갖기 때문에 각각의 객체가 1의 값을 가진다.
예시코드 2
public class Calculator {
public static void main(String[] args) {
Triangle t1 = new Triangle(3.5, 5);
Triangle t2 = new Triangle(7.7, 8.3);
System.out.printf("높이: %.2f, 밑변: %.2f => 넓이: %.2f\n", t1.height, t1.bottomLength, Triangle.area(t1));
System.out.printf("높이: %.2f, 밑변: %.2f => 넓이: %.2f\n", t2.height, t2.bottomLength, Triangle.area(t2));
}
}
class Triangle {
double height;
double bottomLength;
Triangle(double h, double b) {
height = h;
bottomLength = b;
}
static double area(Triangle t) {
return t.height * t.bottomLength * 0.5;
}
}
4. 클래스 메소드 vs 인스턴스 메소드
위의 예시코드에서 static double area(Triangle t) { return t.height * t.bottomLength * 0.5; }는 클래스 메소드이다. Triangle.area(t1)과 Triangle.area(t2)를 보면 Triangle이라는 클래스를 통해서 area() 메소드에 접근하는 것을 볼 수 있다.
만약 double area() { return height * bottomLength * 0.5; }처럼 인스턴스 메소드라면 t1.area()와 t2.area()로 객체를 통해 메소드에 접근해야한다.