Skip to content

Commit efb36eb

Browse files
committed
week1 hoonww
1 parent 8a0fde4 commit efb36eb

File tree

2 files changed

+226
-0
lines changed

2 files changed

+226
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

0715/SSS-week1.md

+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
# Java의 접근제어자
2+
public / private / default / protected<br>
3+
**변수, 메소드, 클래스**(편의상 객체라 하겠다... 이걸 뭐라고 해야하지? 아래에도 계속 객체라고 나올 텐데 어떤 의미에서 사용한 것인지 잘 구분해주세요) 선언 시 붙일 수 있고 해당 객체에 대한 접근을 제한하는데 사용된다.
4+
5+
1. public
6+
* 어느 곳에서든 호출/접근이 가능함
7+
* 접근에 제한을 둘 필요가 없는 객체에 사용
8+
* @Transactional 어노테이션은 public 메소드에 달았을 때만 제 기능으로 동작함
9+
```java
10+
@Transactional // 트랜잭션 정책 적용 안됨
11+
private String method1() { // IntelliJ 에서는 컴파일 에러 발생
12+
...
13+
}
14+
15+
@Transactional // 트랜잭션 정책 적용
16+
public String method2() {
17+
...
18+
}
19+
```
20+
21+
22+
2. protected
23+
* 동일 패키지 또는 하위 클래스에서만 접근이 가능하다.
24+
* 보통은 public으로 해결 가능한 메소드이다. 그렇다면 protected는 언제 왜 사용하는가?
25+
* 하위 클래스에서 Override하여 바꿀 가능성을 열어두는 것
26+
```java
27+
//protected example
28+
public class Man {
29+
protected void attack(){
30+
System.out.println("때리기");
31+
}
32+
}
33+
34+
public class Archer extends Man {
35+
protected void attack(){
36+
System.out.println("활쏘기");
37+
}
38+
}
39+
```
40+
* 위의 예제에서 abstract vs protected 차이점은 무엇일까?<br>
41+
* abstract는 선언 시에 구현을 하지 않고 상속받는 클래스에서 재정의를 필수적으로 요구함
42+
* protected는 재정의를 요구하지 않음
43+
* 다들 김영한 강의를 들으므로... Jpashop에서의 사용 예제(JPA 활용 1편 엔티티 클래스 개발2 14:52~)
44+
```java
45+
package jpabook.jpashop.domain;
46+
47+
import lombok.Getter;
48+
49+
import javax.persistence.Embeddable;
50+
51+
@Embeddable
52+
@Getter
53+
public class Address {
54+
55+
private String city;
56+
private String street;
57+
private String zipcode;
58+
59+
protected Address() {
60+
}
61+
62+
public Address(String city, String street, String zipcode){
63+
this.city = city;
64+
this.street = street;
65+
this.zipcode = zipcode;
66+
}
67+
}
68+
```
69+
city, street, zipcode라는 세 개의 정보를 Address라는 값 타입으로 만든 것이다.<br>
70+
값 타입은 변경 불가능하도록 설계되어야만 해서 setter를 제공하지 않는다.<br>
71+
기본 생성자는 꼭 있어야해서 만들었는데 public은 너무 개방적이고 JPA 스펙 상 protected를 권장한다는 의미로 이해했다<br>
72+
어차피 여기에서의 protected는 큰 의미도 없으므로(다른 누군가 Address 클래스를 상속 받을 일도 없음) 그냥 그른갑다~하고 넘어가자<br>
73+
74+
3. default
75+
* 접근제어자를 생략하면 기본으로 설정된다.
76+
* 같은 패키지 내의 클래스에서 접근이 가능하다.
77+
78+
4. private
79+
* 실질적으로 접근 권한을 '제한'하고 싶을때 주로, 대부분, 통상적으로 private을 쓴다.
80+
* 해당 클래스 내부에서만 사용할 수 있기 때문에 해당 로직(주로 값 변경)이 어딘가에서 무분별하게 호출되는 것을 막기 위해 사용한다.
81+
82+
83+
5. 접근 권한 총 정리
84+
85+
|종류|Class|Package|Lower Class|All|
86+
|---|---|---|---|---|
87+
|public|O|O|O|O|
88+
|protected|O|O|O|X|
89+
|default|O|O|X|X|
90+
|private|O|X|X|X|
91+
92+
# static / final
93+
94+
1. final
95+
96+
final은 **단 한번** 할당될 수 있는 객체에 사용된다. 구현한 코드의 변경이 일어나지 않기를 원할 때 사용하자.
97+
* final로 선언된 변수를 수정하려는 코드가 있으면 에러가 발생한다.
98+
* 아래의 경우는 에러가 발생할까?
99+
```java
100+
public static void main(){
101+
final Item item = new Item();
102+
103+
Item.setName("MacBook Pro"); // 이 때 에러가 발생할까?
104+
}
105+
```
106+
정답 : X; Item 객체가 immutable(불변)한 것은 아니다. 객체의 속성은 변경할 수 있다.
107+
* final 메소드의 경우 오버라이드가 불가능하다.
108+
* final 클래스의 경우 상속이 불가능하다.
109+
110+
김영한 스프링 강의에서 final이 사용됐던 예제를 보자.
111+
```java
112+
@Repository
113+
@RequiredArgsConstructor
114+
public class ItemRepository {
115+
private final EntityManager em;
116+
...
117+
}
118+
```
119+
Repository 계층은 EntityManager의 의존성 주입을 받아야 한다.(받아야 할 것이다)<br>
120+
의존성 주입 방법은 생성자, setter, field 등이 있으나 가장 무난한 것은 생성자를 이용한 주입이다.<br>
121+
그런데 RequiredArgsConstructor 어노테이션은 클래스 내에 final로 선언된 필드의 생성자를 자동으로 생성해준다(Lombok의 힘이다!)<br>
122+
따라서 RequiredArgsConstructor 어노테이션을 넣어주고 final로 선언하면 편하게 의존성 주입을 할 수 있다.
123+
124+
125+
2. static
126+
127+
'객체' 와 '클래스'의 차이점을 안다고 가정하겠다!<br>
128+
static으로 선언된 변수와 메소드는 객체가 아니라 클래스에 묶인다.<br>
129+
따라서!<br>
130+
* 객체를 여러 개 생성해도 클래스에 할당된 메모리 영역에 있으므로 모든 객체가 같은 변수값, 메소드를 **공유**할 수 있다.
131+
* 인스턴스화하지 않아도 static 메소드를 호출할 수 있다.
132+
* Garbage Collector의 관리 영역 밖에 있으므로 프로그램 종료 시까지 메모리에 할당된 상태를 유지한다. 그래서 static 변수, 메소드가 너무 많으면 시스템에 악영향이 있을 수 있다!
133+
134+
static을 사용함으로써 메모리 상의 이득과 손해를 보는 경우를 정리하고 넘어가자.
135+
136+
3. 싱글톤 패턴
137+
138+
static에 대해 알았다면 싱글톤 패턴이 무엇인지 알 수 있다.<br>
139+
싱글톤 : 단 하나의 객체만을 생성하도록 강제하는 패턴
140+
```java
141+
class Singleton {
142+
private static Singleton one;
143+
private Singleton() {
144+
}
145+
146+
public static Singleton getInstance() {
147+
if(one==null) {
148+
one = new Singleton();
149+
}
150+
return one;
151+
}
152+
}
153+
154+
public class Sample {
155+
public static void main(String[] args) {
156+
Singleton singleton1 = Singleton.getInstance();
157+
Singleton singleton2 = Singleton.getInstance();
158+
System.out.println(singleton1 == singleton2); // true 출력
159+
}
160+
}
161+
```
162+
* 장점/사용하는 경우
163+
* 인스턴스를 **하나만** 만들도록 강제해야 하는 상황
164+
* 두 번째 이용(singleton2)의 경우 이미 만들어진 인스턴스를 가져오기만 하므로 로딩 시간이 빠름
165+
* 단점
166+
* 멀티쓰레드 환경에서 동기화를 제대로 안하면 인스턴스가 두 개가 동시에 생성되어 싱글톤 패턴이 깨짐
167+
* 싱글톤이 너무 잡다하게 많은 일, 데이터를 처리하게 되면 객체 지향 설계 원리를 벗어나게 됨
168+
169+
써야 할 때만(그걸 아는게 어렵지만..) 잘 쓰자!
170+
171+
172+
# 뇌절을 쳐보자
173+
```
174+
private 생성자를 가진 클래스를 스프링 빈으로 등록할 수 있을까?
175+
```
176+
먼저 이 질문에 대한 답은 '리플렉션'이라는 개념을 알아야 이해할 수 있을 것 같은데 이는 추후로 넘기도록 하겠다.<br>
177+
내가 공부한 것은 접근제어자이므로 여기에 집중하면, 생성자를 private으로 만들면 new를 이용한 생성이 불가능하고 대신 정적 팩토리 메소드(static factory method)를 이용하여 생성해야 한다.
178+
## 정적 팩토리 메소드(static factory method)
179+
```java
180+
// LocalTime.class
181+
...
182+
public static LocalTime of(int hour, int minute) {
183+
ChronoField.HOUR_OF_DAY.checkValidValue((long)hour);
184+
if (minute == 0) {
185+
return HOURS[hour];
186+
} else {
187+
ChronoField.MINUTE_OF_HOUR.checkValidValue((long)minute);
188+
return new LocalTime(hour, minute, 0, 0);
189+
}
190+
}
191+
...
192+
193+
// hour, minutes을 인자로 받아서 9시 30분을 의미하는 LocalTime 객체를 반환한다.
194+
LocalTime openTime = LocalTime.of(9, 30);
195+
```
196+
* 생성자를 통해 객체를 생성하는 것이 아닌, 어떤 메소드를 통해 객체를 생성하는 것을 정적 팩토리 메소드라고 한다.
197+
* 이를 사용하는 것을 **팩토리 패턴**이라고 한다.
198+
* 생성자와 정적 팩토리 메소드 모두 객체를 생성한다는 동일한 기능을 수행하는 것 같은데, 어떤 차이점이 있는 것인가?
199+
* 장점
200+
1. 이름을 가질 수 있다 : 객체의 생성 목적을 담아낼 수 있다
201+
2. 매번 새로운 객체를 생성하지 않아도 된다
202+
3. 하위 자료형 객체를 반환할 수 있다(2번과 동일한 맥락)
203+
4. 객체 생성을 캡슐화할 수 있다.
204+
205+
-> 좀 더 가독성있고 객체지향적 프로그래밍을 할 수 있게 도와주며, 해당 도메인에서 '객체 생성'이 중요한 역할일 경우 사용하면 좋다.
206+
207+
* 단점
208+
1. 팩토리 메소드만 존재하는 객체는 상속이 불가능하다
209+
210+
211+
212+
## 다음에 공부하고 싶은 내용
213+
* Reflection
214+
* Garbage Collector
215+
216+
217+
## 자료 출처
218+
* https://hyerm-coding.tistory.com/m/95
219+
* https://velog.io/@kmdngmn/Spring-Transactional-privatepublic-%EC%A0%91%EA%B7%BC%EC%A0%9C%EC%96%B4%EC%9E%90
220+
* https://wikidocs.net/232
221+
* https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=2feelus&logNo=220576845725
222+
* https://groups.google.com/g/ksug/c/eg3vxl4D6Bs?pli=1
223+
* https://tecoble.techcourse.co.kr/post/2020-05-26-static-factory-method/
224+
* https://advenoh.tistory.com/13
225+
* https://wikidocs.net/228
226+
* https://coding-factory.tistory.com/524

0 commit comments

Comments
 (0)