public int solution(String ineq, String eq, int n, int m) {
if (ineq.equals(">") && eq.equals("=")){
return n >= m ? 1:0;
}
else if (ineq.equals("<") && eq.equals("=")){
return n <= m ? 1:0;
}
else if (ineq.equals("<") && eq.equals("!")){
return n < m ? 1:0;
}
else {
return n > m ? 1:0;
}
}
class NormalCounter {
private int count = 0;
public NormalCounter(){ // 생성자
count++;
}
public int getCount(){ // getter
return count;
}
}
public class Ex01_NormalCounter {
public static void main(String[] args) {
NormalCounter counter = new NormalCounter();
NormalCounter counter2 = new NormalCounter();
System.out.println(counter.getCount());
System.out.println(counter2.getCount());
}
}
public class Ex02_StaticCounter {
public static void main(String[] args) {
StaticCounter s1 = new StaticCounter();
StaticCounter s2 = new StaticCounter();
System.out.println(s1.getCount());
System.out.println(s2.getCount());
}
}
class StaticCounter{
private static int count = 0;
public StaticCounter(){
count++;
}
public int getCount(){
return count;
}
}
원래는 자바 파일을 만들때 컴파일 명령어(javac Test.java)를 입력하여 일일히 컴파일(.class파일로) 해야하지만 java extension pack 같은 곳에서는 파일을 쓰고 수정할때마다 자동으로 컴파일 해준다.
클래스 로딩(f5를 누르는 순간 시작된다.): jvm 실행 -> 클래스 로딩 -> 클래스 링크(클래스와 다른 클래스나 변수와 연결 등) -> 클래스 초기화(메서드 영역과 static 변수 생성됨) -> 메인 메서드 실행
프로그램 종료: 프로그램 종료는 = jvm 종료이고 main의 실행이 끝나면 jvm은 종료된다. 종료와 함께 모든 매서드, 힙 영역과 static변수가 삭제된다.
기본적으로 클래스는 메서드 영역에 생성될때 주소로 생성되는 것이 아니라 이름 자체로 생성된다. 이때 클래스가 로딩되면서 static 변수들이 클래스 내부의 영역으로 함께 생성된다. 즉 클래스의 공간안에 static 매서드와 변수가 있는 것이다.
"static 변수는 클래스 내부에 소속되어, 클래스 이름으로 바로 접근된다." int value = TestClass.staticNum;
"집을 지을 때 설계도의 정보는 그대로 두고" (static 정보 유지), "각각의 집(객체)이 개별적인 정보를 가지며 살아가는 것"(인스턴스 변수 개별 생성)이다. 즉 한번 설계도(클래스)에서 객체로 정보를 들고 나오면(객체가 생성되면), 객체는 다시 클래스에 자신의 정보를 되돌리지 않고, 각자의 길을 가게 되는 일방적인 흐름이다. (클래스의 참조값 같은게 필요없는 이유)
변수(current)는 참조값(객체의 주소) 을 저장하기 위해 존재.
객체(new CalcSingleTon())는 자신이 어떤 클래스인지 JVM 내부의 클래스 정보를 가지고 있음.
둘이 연결될 수 있는 이유는 변수가 "클래스 이름"으로 타입을 지정해, 해당 클래스의 객체 주소만 저장할 수 있기 때문.
객체는 static 변수를 어떻게 참조?: 객체 → 클래스 정보(Method Area) → static 변수 (간접 참조)
클래스는 주소가 없는데 어떻게 접근?: JVM 내부 클래스 로더가 클래스 이름을 이용해 클래스 정보(Method Area) 접근 (내부적인 해시맵 사용)
private 변수는 어떻게 찾음?: 클래스 내부 메서드끼리는 컴파일 단계에서 변수 위치를 직접 알고 접근 가능, 외부는 컴파일 단계에서 접근 제한
클래스도 메모리 공간을 점유하고 있는 실체이다.
private로 선언되면 class내부가 아니면 class를 직접 타고 오더라도 선언할 수 없다.
public class CalcSingleTon {
private static CalcSingleTon current; // 클래스가 로딩될때 하나만 만들어짐. 변수이고 객체의 주소를 보관할 참조형 변수 // static은 고향의 공용 꿀단지 볼라면 public(공적인) 경로로 봐야 한다.
public static CalcSingleTon getInstance(){ // 고향의 공용 서비스라 마을 이름으로 접근해야함. 사람들(객체)에게 가서 이용할 수 없음. 마을이 실체니까 아무리 private이어도 같은 마을에 있으니까 current의 존재를 안다. 떠나간 사람들은 마을을 직접 볼 수 없으므로 들고오지(public) 않는 이상 확인할 수 없다. 요청시 마을로 가서 직접 알려주어야함.
if (current == null){
current = new CalcSingleTon(); // 객체 주소를 할당 // 객체 생성을 제한할때 기능적으로 제약을 둬야하므로 메서드를 활용
}
return current;
}
private CalcSingleTon(){ // 생성자란 객체를 호출할 때 생성되어 객체의 초기화를 담당한다. new를 쓸 수 없다. 정확히 말하면 생성자는 객체 생성 시점에서 "반드시 호출되어야만 하는 필수 메서드"이고, 이 메서드가 외부에서 보이지 않으면(private) 호출 자체가 불가능하게 되는 것. 즉 객체를 만들 수 있다는 건 알지만 그 정확한 비법을 몰라서 못만드는 느낌.
System.out.println("싱글턴에 대한 current 객체 생성");
}
public int plus(int x, int y) {return x + y;}
public int minus(int x, int y) {return x - y;}
public int times(int x, int y) {return x * y;}
public int divied(int x, int y) {return x / y;}
class SingleTonPattern{
public static void main(String[] args) {
int x = 100;
int y = 50;
CalcSingleTon cs1 = CalcSingleTon.getInstance();
System.out.printf("%d + %d = %d\n", x, y, cs1.plus(x, y));
CalcSingleTon cs2 = CalcSingleTon.getInstance();
System.out.printf("%d - %d = %d\n", x, y, cs2.minus(x, y));
CalcSingleTon cs3 = CalcSingleTon.getInstance();
System.out.printf("%d * %d = %d\n", x, y, cs3.times(x, y));
CalcSingleTon cs4 = CalcSingleTon.getInstance();
System.out.printf("%d / %d = %d\n", x, y, cs4.divied(x, y));
System.out.println(CalcSingleTon.current);
}
}
}