TIL

157일차(모험 66일차) - 회원 도메인 개발(public, void, static 유무)

haedal-uni 2022. 2. 17. 23:46
728x90

[add] 회원 도메인 개발 [#1]

 

getter와 setter 추가

- 단축키 alt + ins

(실제 프로젝트 할 때는 어노테이션으로 했었다.)

 

 

이후 코드를 보며 생각나는 궁금증에 대해 정리를 했다.

 


동시성 문제 - ConcurrentHashMap을 사용해야하지만 예시이므로 HashMap 사용

 

HashMap과 ConcurrentHashMap의 차이점

1) Thread Safe

주요 차이점은 ConcurrentHashMap는 내부적 동기화 때문에 스레드가 Safe한다.

HashMap는 내부적으로 동기화되지 않고 스레드로부터 안전하지 않다.

HashMap 메서드를 사용하여 외부에서 동기화 할 수 있다.

 

결론적으로 ConcurrentHashMap는 내부적으로 동기화 함으로, 동시 멀티 쓰레드 어플리케이션에 적합하다.

HashMap은 내부적으로 동기화 되지않는다. 따라서 단일 쓰레드 프로그램에 적합하다.

 

 

 

그 외 차이점 >>  [ [동시성 이슈해결] HashMap보다는 ConcurrentHashMap을 쓰자! ]


public 유무?

➡️ 접근 제어자

  • public
    어떤 클래스에서라도 접근이 가능하다.

 

  • protected
    클래스가 정의되어 있는 해당 패키지 내 그리고 해당 클래스를 상속받은 외부 패키지의 클래스에서 접근이 가능하다.

 

  • (default)
    클래스가 정의되어 있는 해당 패키지 내에서만 접근이 가능하도록 접근 범위를 제한한다.

 

  • private
    정의된 해당 클래스에서만 접근이 가능하도록 접근 범위를 제한한다.

 

* 패키지? → 디렉토리(폴더)

 

 

Interview_Question_for_Beginner ]

[JAVA] 15. 패키지(package) & 접근제어자 ]


void 유무?

void의 역할은 return 되는 타입이 없음을 의미한다. 

즉, 아무것도 리턴하지 않음을 선언해주는 것과 같다.

 

 

예제

public void test() {
  siteurl = 'webisfree.com';
}

위 함수 test()는 void로 리턴타입을 선언하였다.

만약 리턴타입이 다르다면 실제 함수의 리턴값도 동일해야한다.

 

아래는 string이므로 문자열을 리턴해야한다.

 

public string getUrl() {
  return 'webisfree.com';
}

만약 문자열이 아니라면 에러가 발생한다.

 

 

 

자바에서 사용되는 Void란 무엇인가? ] 


static 유무?

➡️ 클래스 메소드(static 메소드) vs 인스턴스 메소드

Static 키워드를 사용한다는 것은 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미한다.


static 변수

- 클래스 변수

- 클래스가 정의만 되어도 접근이 가능한 변수

(인스턴스 변수는 인스턴스가 생성되었을 때 접근 가능)

- 객체 생성 없이 호출이 가능한 메소드

- 메모리에 고정적으로 할당되어, 프로그램이 종료될 때 해체되는 변수

 

 

 

메모리

 

https://mangkyu.tistory.com/47

 

일반적으로 우리가 만든 Class는 Static 영역에 생성되고, 

new 연산을 통해 생성한 객체는 Heap영역에 생성된다.

객체의 생성시에 할당된 Heap영역의 메모리는 Garbage Collector를 통해 수시로 관리를 받는다.

 

하지만 Static 키워드를 통해 Static 영역에 할당된 메모리는

모든 객체가 공유하는 메모리라는 장점을 지니지만,

Garbage Collector의 관리 영역 밖에 존재하므로 Static을 자주 사용하면

프로그램의 종료시까지 메모리가 할당된 채로 존재하므로 자주 사용하게 되면

시스템의 퍼포먼스에 악영향을 주게 된다.

Static 변수와 static 메소드는 Static 메모리 영역에 존재하므로

객체가 생성되기 이전에 이미 할당이 되어 있다.

그렇기 때문에 객체의 생성없이 바로 접근(사용)할 수 있다. 

public class MyCalculator { 
    public static String appName = "MyCalculator"; 
    
        public static int add(int x, int y) { 
            return x + y; 
        } 
        
        public int min(int x, int y) { 
            return x - y; 
        } 
} 

MyCalculator.add(1, 2); // static 메소드 이므로 객체 생성 없이 사용 가능 
MyCalculator.min(1, 2); // static 메소드가 아니므로 객체 생성후에 사용가능 

MyCalculator cal = new MyCalculator(); 
cal.add(1, 2); // o 가능은 하지만 권장하지 않는 방법 
cal.min(1, 2); // o

 

 

 

 

Static 변수(정적 변수)

세상 모든 사람의 이름이 'MangKyu'인 세상에 살고있다고 가정을 한다.

이럴때면 우리는 아래와 같이 객체를 만들 수 있다.

public class Person { 
    private String name = "MangKyu";  
    
        public void printName() { 
            System.out.println(this.name); 
         }
}


하지만 위와 같은 클래스를 통해 100명의 Person 객체를 생성하면,

"MangKyu"라는 같은 값을 갖는 메모리가 100개나 중복해서 생성되게 된다.

 

이러한 경우에 static을 사용하여 여러 객체가 하나의 메모리를 참조하도록 하면

메모리 효율이 더욱 높아질 것이다.

 

또한 "MangKyu"라는 이름은 결코 변하지 않는 값이므로 final 키워드를 붙여주며,

일반적으로 Static은 상수의 값을 갖는 경우가 많으므로 public으로 선언을 하여 사용한다.

이러한 이유로, 일반적으로 static 변수는 public 및 final과 함께 사용되어 public static final로 활용 된다. 

public class Person {
    public static final String name = "MangKyu";
    
    public static void printName() {      
        System.out.println(this.name);   
    } 
}

 

 

 

 

Static 메소드(정적 메소드)

public class Test { 
	private String name1 = "MangKyu"; 
	private static String name2 = "MangKyu"; 
    
	public static void printMax(int x, int y) { 
		System.out.println(Math.max(x, y)); 
} 

	public static void printName(){
		// System.out.println(name1); 불가능한 호출 
		System.out.println(name2); 
	} 
}

static 메소드에서는 static이 선언되지 않은 변수에 접근이 불가능한데, 

메모리 할당과 연관지어 생각해보면 당연하다.

 

우리가 Test.printName() 을 사용하려고 하는데,

name1은 new 연산을 통해 객체가 생성된 후에 메모리가 할당된다.

 

하지만 static 메소드는 객체의 생성 없이 접근하는 함수이므로,

할당되지 않은 메모리 영역에 접근을 하므로 문제가 발생하게 된다.

그러므로 static 메소드에서 접근하기 위한 변수는 반드시 static 변수로 선언되어야 한다.

 

 

 

[Java] static변수와 static 메소드 ]

 

 

더보기
더보기

+)

static 키워드로 생성된 변수는 해당 변수가 있는 클래스 로드 중에 초기화되며,

애플리케이션 실행 내내 메모리에 머물러 있다.

따라서 초기화 과정 없이 해당 변수, 메소드에 접근할 수 있다.

 

 

public class Calculator {
    public static int result = 0;

    public int add(int num1, int num2) {
        result = num1 + num2;
        return result;
    }
}

 

public class Main {
    public static void main(String[] args) {

        Calculator calculator1 = new Calculator();
        calculator1.add(2, 2);
        
        System.out.println(calculator1.result);

        Calculator calculator2 = new Calculator();
        calculator2.add(3, 3);
        
        System.out.println(calculator2.result);
        System.out.println(calculator1.result);
        
    }
}
결과)
System.out.println(calculator1.result); / 4   // (클래스 이름(Calculator)로 바로 접근)
System.out.println(calculator2.result); / 6   // (클래스 이름(Calculator)로 바로 접근)
System.out.println(calculator1.result); / 6   // (클래스 이름(Calculator)로 바로 접근)

 

 

➡️ static 키워드를 가진 변수는 인스턴스의 생성 개수에 상관없이 공통으로 하나만 사용된다.

 

 

 

non-static(static 키워드 없이 생성된) 변수는 새로운 객체(인스턴스)를 생성할 때마다 초기화된다.

static 키워드가 없는 변수를 인스턴스 변수라고 부른다.  

Calculator 클래스에 non-static 변수가 있다면.
public static int result = 0;

결과)
System.out.println(calculator1.result); / 4
System.out.println(calculator2.result); / 6
System.out.println(calculator1.result); / 4

non-static 변수는 인스턴스를 새로 생성 할 때마다 변수가 새롭게 초기화된다. 

변수 하나로 공용으로 사용하지 않는다.

 

 

[Java] static 키워드 유무에 따른 변수 값의 변화 ]

 

 

728x90