λ°μ΄ν„°λ² μ΄μŠ€μ—μ„œ ν•„μˆ˜λ‘œ μ“°μ΄λŠ” λ‚ μ§œν˜• 데이터에 λŒ€ν•΄ μ •λ¦¬ν•΄λ‘κ³ μž ν•©λ‹ˆλ‹€.

4κ°€μ§€ μœ ν˜•μ˜ 데이터 νƒ€μž…μ— λŒ€ν•œ 정리와 μΌμžμ™€ μ‹œκ°„μ„ λͺ¨λ‘ ν‘œν˜„ν•˜λŠ” DATETIMEκ³Ό TIMESTAMP의 차이λ₯Ό μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

1. DATE, DATETIME, TIMESTAMP, TIME

MySQLμ—μ„œλŠ” μΌμžμ™€ μ‹œκ°„μ„ ν‘œν˜„ν•˜κΈ°μœ„ν•΄ DATE, DATETIME, TIMESTAMP, TIME νƒ€μž…μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  DATE DATETIME TIMESTAMP TIME
상세 일자만 ν‘œν˜„ - μΌμžμ™€ μ‹œκ°„ ν‘œν˜„
- μ΅œλŒ€ λ§ˆμ΄ν¬λ‘œμ΄ˆ μ •λ°€λ„μ˜ μ†Œμˆ˜ μ΄ˆλ₯Ό ν¬ν•¨ κ°€λŠ₯
- ν˜„μž¬ λ‚ μ§œμ™€ μ‹œκ°„μœΌλ‘œ μžλ™ μ΄ˆκΈ°ν™” λ° μ—…λ°μ΄νŠΈκ°€ κ°€λŠ₯
- μΌμžμ™€ μ‹œκ°„ ν‘œν˜„
- (default) NOT NULL
- Timezone 기반
- μ΅œλŒ€ λ§ˆμ΄ν¬λ‘œμ΄ˆ μ •λ°€λ„μ˜ μ†Œμˆ˜ μ΄ˆλ₯Ό ν¬ν•¨ κ°€λŠ₯
- ν˜„μž¬ λ‚ μ§œμ™€ μ‹œκ°„μœΌλ‘œ μžλ™ μ΄ˆκΈ°ν™” λ° μ—…λ°μ΄νŠΈκ°€ κ°€λŠ₯
μ‹œκ°„λ§Œ ν‘œν˜„
ν˜•μ‹ YYYY-MM-DD YYYY-MM-DD hh:mm:ss YYYY-MM-DD hh:mm:ss hh:mm:ss
λ²”μœ„ '1000-01-01'
~'9999-12-31'
'1000-01-01 00:00:00'
~ '9999-12-31 23:59:59'
'1970-01-01 00:00:01' UTC
~ '2038-01-19 03:14:07' UTC
'-838:59:59' ~'838:59:59' 
μš©λŸ‰ 3byte 8byte 4byte 3byte

 

μΌμžμ™€ μ‹œκ°„μ„ λͺ¨λ‘ ν‘œν˜„ν•˜λŠ” DATETIMEκ³Ό TIMESTAMPλŠ” μ–Όν•λ΄μ„œλŠ” λΉ„μŠ·ν•œλ°, 차이점이 μžˆμŠ΅λ‹ˆλ‹€. 

이 λ‘˜μ˜ 차이λ₯Ό μ•Œκ³  μžˆμ–΄μ•Ό μ˜ˆμƒμΉ˜ λͺ»ν•œ μ—λŸ¬μ‚¬ν•­μ„ λŒ€λΉ„ν•  수 있기 λ•Œλ¬Έμ—, 차이점을 ν•œ 번 μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

2. DATETIME vs TIMESTAMP

1) λ²”μœ„

μΌμžμ™€ μ‹œκ°„μ„ λͺ¨λ‘ ν‘œν˜„ν•˜λŠ” 두 νƒ€μž…μ€ 일단 ν‘œμ—μ„œ λ³Ό 수 μžˆλ“― λ²”μœ„μ—μ„œ 차이가 μžˆμŠ΅λ‹ˆλ‹€.

DATETIME의 λ²”μœ„λŠ” '1000-01-01 00:00:00' λΆ€ν„° '9999-12-31 23:59:59' 둜, μ‹œκ°„λŒ€μ— 관계없이 μ ˆλŒ€μ μΈ μΌμžμ™€ μ‹œκ°„μ„ μ €μž₯ν•©λ‹ˆλ‹€.

TIMESTAMP의 λ²”μœ„λŠ” '1970-01-01 00:00:01' UTC λΆ€ν„° '2038-01-19 03:14:07' UTC 둜, 데이터가 UTC둜 λ³€ν™˜λ˜μ–΄ μ €μž₯되며 κ²€μƒ‰μ‹œ ν˜„μž¬ μ‹œκ°„λŒ€λ‘œ λ³€ν™˜μ΄ λ©λ‹ˆλ‹€. TIMESTAMP의 λ²”μœ„λŠ” Unix μ‹œκ°„κ³Ό 관련이 μžˆμ–΄, 2038λ…„ 문제둜 인해 μ΅œλŒ€ λ²”μœ„κ°€ 2038λ…„κΉŒμ§€λ‘œ μ œν•œλ©λ‹ˆλ‹€.

2) Timezone의 적용 μ—¬λΆ€

두 νƒ€μž…μ€ Timezone의 적용 여뢀에 차이가 μžˆμŠ΅λ‹ˆλ‹€.

Timezone은 λ™μΌν•œ μ‹œκ°„μ„ λ”°λ₯΄λŠ” 지역을 μ˜λ―Έν•˜κ³ , ν•΄λ‹Ή ꡭ가에 μ˜ν•΄ λ²•μ μœΌλ‘œ μ§€μ •λ˜λŠ” κ°’μž…λ‹ˆλ‹€.

UTC, Asia/Seoul λ“±μ˜ ν‘œκΈ°κ°€ ν•΄λ‹Ή μ‹œκ°„μ΄ μ–΄λ–€ λ‘œμ»¬μ„ κΈ°μ€€μœΌλ‘œ μž‘μ„±ν•œ 것인지λ₯Ό λͺ…μ‹œν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

 

MySQL은 TIMESTAMP 값을 ν˜„μž¬ μ‹œκ°„λŒ€μ—μ„œ *UTC둜 λ³€ν™”ν•˜μ—¬ μ €μž₯ν•˜κ³ , λ‹€μ‹œ UTCμ—μ„œ ν˜„μž¬ μ‹œκ°„λŒ€λ‘œ λ³€ν™˜ν•˜μ—¬ κ²€μƒ‰ν•©λ‹ˆλ‹€.

*UTC: ꡭ제 ν‘œμ€€μ‹œ

기본적으둜 μ„€μ •λ˜λŠ” μ‹œκ°„λŒ€λŠ” μ„œλ²„ μ‹œκ°„μœΌλ‘œ, μ‹œκ°„λŒ€ 섀정이 μΌμ •ν•˜κ²Œ μœ μ§€λœλ‹€λ©΄ μ €μž₯ν•œ κ°’κ³Ό λ™μΌν•œ 값을 λ°˜ν™˜λ°›μŠ΅λ‹ˆλ‹€.

λ§Œμ•½ TIMESTAMP 값을 μ €μž₯ν•œ ν›„, μ‹œκ°„λŒ€λ₯Ό λ³€κ²½ν•˜κ³  값을 μ‘°νšŒν•˜λ©΄, 쑰회 κ²°κ³ΌλŠ” μ €μž₯ν•œ κ°’κ³Ό λ‹€λ₯΄κ²Œ λ©λ‹ˆλ‹€. μ‹œκ°„λŒ€ λ³€ν™˜μ‹œ λ™μΌν•œ μ‹œκ°„λŒ€λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— μ΄λŸ¬ν•œ κ²°κ³Όκ°€ λ°œμƒν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

*ν˜„ μ‹œκ°„λŒ€λŠ” μ‹œμŠ€ν…œ λ³€μˆ˜μΈ time_zone 에 μ„€μ •λœ κ°’μœΌλ‘œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ‹œ

μ‹€μ œλ‘œ 데이터가 μ–΄λ–»κ²Œ μ €μž₯λ˜λŠ”μ§€ ν™•μΈν•΄λ΄…μ‹œλ‹€.

create table date_example
(
  test_date date,
  test_datetime datetime,
  test_timestamp timestamp,
  test_time time
);

insert into date_example values (now(), now(), now(), now());

ν…ŒμŠ€νŠΈ ν…Œμ΄λΈ”μ„ λ§Œλ“€κ³  ν˜„μž¬ μ‹œκ°„μœΌλ‘œ 데이터λ₯Ό μ €μž₯ν–ˆμŠ΅λ‹ˆλ‹€.

mysql> select * from date_example;
+------------+---------------------+---------------------+-----------+
| test_date  | test_datetime       | test_timestamp      | test_time |
+------------+---------------------+---------------------+-----------+
| 2024-07-09 | 2024-07-09 10:36:17 | 2024-07-09 10:36:17 | 10:36:17  |
+------------+---------------------+---------------------+-----------+
1 row in set (0.00 sec)

μ™Όμͺ½λΆ€ν„° DATE, DATETIME, TIMESTAMP, TIME ν˜•μ‹μ˜ 데이터가 μ €μž₯된 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

μ—¬κΈ°μ„œ time_zone을 μˆ˜μ •ν•΄λ³΄κ³  λ‹€μ‹œ 같은 데이터λ₯Ό ν™•μΈν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

mysql> SET time_zone = '+01:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_example;
+------------+---------------------+---------------------+-----------+
| test_date  | test_datetime       | test_timestamp      | test_time |
+------------+---------------------+---------------------+-----------+
| 2024-07-09 | 2024-07-09 10:36:17 | 2024-07-09 02:36:17 | 10:36:17  |
+------------+---------------------+---------------------+-----------+
1 row in set (0.00 sec)

time_zone에 λ³€ν™”λ₯Ό μ£Όκ³  μ‘°νšŒν•΄λ³΄λ‹ˆ TIMESTAMP ν˜•μ‹μ˜ test_timstamp κ°’λ§Œ λ³€ν•œ 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

  • SET time_zone = '+01:00' : UTC+09:00 보닀 8μ‹œκ°„ μ΄μ „μœΌλ‘œ μ„€μ •

μ΄λŠ” μœ„μ—μ„œ κΈ°μž¬ν–ˆλ“― TIMESTAMP λŠ” μ‹œμŠ€ν…œ λ³€μˆ˜μΈ time_zone을 κΈ°μ€€μœΌλ‘œ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

κ·Έλ ‡κΈ°λ•Œλ¬Έμ— TIMESTAMPλ₯Ό μ‚¬μš©ν•˜κ³ , 둜컬 μ‹œκ°„μ΄ λ‹€λ₯Έ κΈ€λ‘œλ²Œ μ„œλΉ„μŠ€λ₯Ό μš΄μ˜ν•  λ•Œμ—λŠ” 이λ₯Ό μœ μ˜ν•΄μ„œ κ΄€λ¦¬ν•΄μ•Όν•©λ‹ˆλ‹€.

 

TIMESTAMPλ₯Ό μ‚¬μš©ν•˜λ©΄ 둜컬 μ‹œκ°„μ— 따라 ν˜Όλž€μ΄ μžˆμ„ μˆ˜λŠ” μžˆμœΌλ‚˜, κΈ€λ‘œλ²Œ μ„œλΉ„μŠ€λ₯Ό μš΄μ˜ν• λ•Œμ—λŠ” μœ μš©ν•˜κ²Œ 쓰일 수 μžˆμŠ΅λ‹ˆλ‹€.

λ§Œμ•½ DATETIME을 μ‚¬μš©ν•œλ‹€λ©΄ 둜컬 μ‹œκ°„μ΄ μ œλŒ€λ‘œ λ°˜μ˜λ˜μ§€ μ•Šμ•„μ„œ, μ„œμšΈμ—μ„œ μ˜€μ „ 11μ‹œμ— μž‘μ„±ν•œ 글을 λ―Έκ΅­μ—μ„œ μ‘°νšŒν•˜λŠ” 경우, λ™μΌν•˜κ²Œ μ˜€μ „ 11μ‹œλ‘œ λ°˜μ˜λ˜λŠ” λ“±μ˜ λ¬Έμ œκ°€ λ°œμƒν•©λ‹ˆλ‹€. μ΄λ ‡κ²Œ μ‹œκ°„μ΄ λ‹€λ₯Έ 지역이 μžˆλŠ” 경우, TIMESTAMPκ°€ 더 적합할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

 

μ΄λŸ¬ν•œ νŠΉμ§•λ“€λ‘œ DATETIME은 μ ˆλŒ€μ μΈ μ‹œκ°„ 기둝에 μ ν•©ν•˜κ³  TIMESTAMPλŠ” μ‹œκ°„λŒ€μ— 따라 λ³€ν™˜μ΄ ν•„μš”ν•œ 경우 μœ μš©ν•˜κ²Œ μ“°μž…λ‹ˆλ‹€.

3) DATETIME κ³Ό TIMESTAMP의 μžλ™ μ΄ˆκΈ°ν™”

DATETIME와 TIMESTAMPλŠ” ν˜„μž¬ μΌμžμ™€ μ‹œκ°„μ„ κΈ°λ³Έκ°’, μžλ™ μ—…λ°μ΄νŠΈ κ°’μœΌλ‘œ μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • μžλ™ μ΄ˆκΈ°ν™”: 데이터 μ‚½μž…μ‹œ λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜μ§€ μ•Šμ•„λ„ ν˜„μž¬ νƒ€μž„μŠ€νƒ¬ν”„λ‘œ μ„€μ •
  • μžλ™ μ—…λ°μ΄νŠΈ: 데이터 κ°±μ‹ μ‹œ μžλ™μœΌλ‘œ ν˜„μž¬ νƒ€μž„ μŠ€νƒ¬ν”„λ‘œ κ°±μ‹ 

μ„€μ • 방법

μžλ™ μ΄ˆκΈ°ν™”μ™€ μ—…λ°μ΄νŠΈλ₯Ό μ„€μ •ν•˜λ €λ©΄ DATETIMEκ³Ό TIMESTAMP μ—΄ μ •μ˜μ—μ„œ μ§€μ •ν•΄μ£Όλ©΄ λ©λ‹ˆλ‹€.

  • μžλ™ μ΄ˆκΈ°ν™”λ₯Ό μœ„ν•œ μ΄ˆκΈ°κ°’ μ„€μ •: DEFAULT ~~
  • μžλ™ μ—…λ°μ΄νŠΈλ₯Ό μœ„ν•œ μ„€μ •: ON UPDATE ~~

DATETIMEκ³Ό TIMESTAMPλ₯Ό 각각 ν˜•μ‹μœΌλ‘œ κ°€μ§€λŠ” column이 μžˆλŠ” ν…Œμ΄λΈ”μ„ μ•„λž˜μ™€ 같이 μ •μ˜ν•˜λ©΄ μžλ™μœΌλ‘œ 값이 λ“€μ–΄κ°‘λ‹ˆλ‹€.

CREATE TABLE t1 (
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

μœ„ ν…Œμ΄λΈ”μ— 아무 값도 μ§€μ •ν•˜μ§€ μ•Šκ³  INSERTλ₯Ό ν•˜κ³  쑰회λ₯Ό ν•˜λ©΄, 

insert into t1 values();

아무 값도 λ„£μ§€ μ•Šμ•˜λŠ”λ°λ„ ν˜„μž¬ μ‹œκ°„μ΄ μ €μž₯된 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

mysql> select * from t1;
+---------------------+---------------------+
| ts                  | dt                  |
+---------------------+---------------------+
| 2024-07-09 12:13:49 | 2024-07-09 12:13:49 |
+---------------------+---------------------+
1 row in set (0.00 sec)

 

μ΄λ²ˆμ—” μ•„λž˜μ™€ 같은 ν…Œμ΄λΈ”μ„ μƒμ„±ν•΄λ΄…μ‹œλ‹€.

CREATE TABLE t1 (
  ts TIMESTAMP DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  dt DATETIME DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP
);

μœ„μ—μ„œ μ •μ˜ν•œ 것과 λ‹€λ₯Έμ μ€ DEFAULT NULL λΆ€λΆ„μž…λ‹ˆλ‹€.

μ΄λŠ” 기본값을 NULL둜 λ‘κ² λ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.

 

mysql> INSERT INTO t1 VALUES();
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM T1;
+------+------+
| ts   | dt   |
+------+------+
| NULL | NULL |
+------+------+
1 row in set (0.00 sec)

μœ„μ™€ λ™μΌν•˜κ²Œ 아무 값도 λ„£μ§€ μ•Šκ³  INSERTλ₯Ό ν•˜λ©΄, μ΄λ²ˆμ—λŠ” NULL 값이 μ €μž₯된 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.


마치며,

μ„œλΉ„μŠ€λ₯Ό μš΄μ˜ν•˜λ©΄ ν•„μˆ˜μ μœΌλ‘œ ν¬ν•¨λ˜λŠ” λ‚ μ§œμ™€ μ‹œκ°„ λ°μ΄ν„°ν˜•μ— λŒ€ν•œ λ‚΄μš©μ„ μ •λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.

특히 DATETIMEκ³Ό TIMESTAMP의 μ°¨μ΄μ—μ„œ ν—·κ°ˆλ¦¬λŠ” 뢀뢄이 λ§Žμ•˜λŠ”λ°, μ΄λ²ˆμ— μ •λ¦¬ν•˜κ³  μ°Ύμ•„λ³΄λ©΄μ„œ ν•œλ²ˆ 더 확인할 수 μžˆμ—ˆλ˜ μ‹œκ°„μ΄μ—ˆμŠ΅λ‹ˆλ‹€. λ‚ μ§œ 데이터와 κ΄€λ ¨ν•΄μ„œλŠ” λ‹€μŒμ— λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•˜λŠ” λ“± μ‹€μ œλ‘œ 값을 μ‘°νšŒν•˜κ³  μ²˜λ¦¬ν•˜λŠ” 뢀뢄에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

Reference

 

MySQL :: MySQL 8.4 Reference Manual :: 13.2.2 The DATE, DATETIME, and TIMESTAMP Types

13.2.2 The DATE, DATETIME, and TIMESTAMP Types The DATE, DATETIME, and TIMESTAMP types are related. This section describes their characteristics, how they are similar, and how they differ. MySQL recognizes DATE, DATETIME, and TIMESTAMP values in several f

dev.mysql.com

 

MySQL :: MySQL 8.4 Reference Manual :: 13.2.5 Automatic Initialization and Updating for TIMESTAMP and DATETIME

13.2.5 Automatic Initialization and Updating for TIMESTAMP and DATETIME TIMESTAMP and DATETIME columns can be automatically initialized and updated to the current date and time (that is, the current timestamp). For any TIMESTAMP or DATETIME column in a ta

dev.mysql.com

'πŸ’» Programming > SQL' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[SQL] μˆœμœ„ ν•¨μˆ˜(MySQL, Oracle)  (0) 2024.07.08

πŸ“Œμš”μ•½

μœˆλ„μš° ν•¨μˆ˜ 쀑 ν•˜λ‚˜μΈ μˆœμœ„ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ κ²°κ³Ό μ§‘ν•©μ˜ 각 행에 μˆœμœ„λ₯Ό ν• λ‹Ήν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  RANK() DENSE_RANK() ROW_NUMBER()
동일 κ°’ 처리 동일 μˆœμœ„ λΆ€μ—¬ 동일 μˆœμœ„ λΆ€μ—¬ 각 행별 고유 μˆœμœ„ λΆ€μ—¬
μˆœμœ„ 간격 동일 μˆœμœ„μžˆλŠ” 경우,
κ·Έ λ‹€μŒ μˆœμœ„λŠ” 이전 동일 μˆœμœ„λ₯Ό κ°€μ§„ ν–‰ 수만큼의 간격 λ°œμƒ
동일 μˆœμœ„κ°€ μžˆμ–΄λ„,
μˆœμœ„λ₯Ό κ±΄λ„ˆλ›°μ§€ μ•Šκ³ (간격 없이) μ—°μ†λœ μˆœμœ„λ₯Ό λΆ€μ—¬
동일 μˆœμœ„κ°€ μžˆμ–΄λ„,
각 ν–‰μ—λŠ” 순차적으둜 μœ λ‹ˆν¬ν•œ μˆœμœ„ λΆ€μ—¬
μ˜ˆμ‹œ 1,2,2,4,5, ... 1,2,2,3,4, ... 1,2,3,4,5, ...

 


1. RANK() ν•¨μˆ˜

[MySQL Tutorial]
RANK() ν•¨μˆ˜λŠ” κ²°κ³Ό μ§‘ν•©μ˜ νŒŒν‹°μ…˜ λ‚΄ 각 행에 μˆœμœ„λ₯Ό ν• λ‹Ήν•©λ‹ˆλ‹€.
ν–‰μ˜ μˆœμœ„λŠ” 1에 κ·Έ μ•žμ— μ˜€λŠ” μˆœμœ„ 수λ₯Ό λ”ν•œ κ°’μœΌλ‘œ μ§€μ •λ©λ‹ˆλ‹€.

[Oracle Tutorial]
RANK() ν•¨μˆ˜λŠ” 각 μ§‘ν•©μ—μ„œ κ°’μ˜ μˆœμœ„λ₯Ό κ³„μ‚°ν•˜λŠ” 뢄석 ν•¨μˆ˜μž…λ‹ˆλ‹€.
RANK() ν•¨μˆ˜λŠ” λ™μΌν•œ 값을 κ°€μ§„ 행에 λŒ€ν•΄ λ™μΌν•œ μˆœμœ„λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. 동λ₯  μˆœμœ„μ— 동λ₯  ν–‰ 수λ₯Ό 더해 λ‹€μŒ μˆœμœ„λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€. λ”°λΌμ„œ μˆœμœ„λŠ” μ—°μ†λœ μˆ«μžκ°€ 아닐 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
RANK() ν•¨μˆ˜λŠ” μƒμœ„ N 및 ν•˜μœ„ N 쿼리에 μœ μš©ν•©λ‹ˆλ‹€.

 

RANK() ν•¨μˆ˜λŠ” μœˆλ„μš° ν•¨μˆ˜ 쀑 κ·Έλ£Ή λ‚΄ μˆœμœ„ ν•¨μˆ˜λ‘œ, νŠΉμ • μœˆλ„μš°(λΆ€λΆ„)λ‚΄μ—μ„œ μˆœμœ„λ₯Ό ν• λ‹Ήν•˜λŠ” 데 μ‚¬μš©ν•©λ‹ˆλ‹€.

λ™μΌν•œ 값을 κ°€μ§„ 행에 λŒ€ν•΄ λ™μΌν•œ μˆœμœ„λ₯Ό λΆ€μ—¬ν•˜κ³  κ·Έ λ‹€μŒ μˆœμœ„λŠ” 동일 μˆœμœ„λ₯Ό κ°€μ§„ ν–‰ 수만큼의 μ‹œν€€μŠ€ 간격이 μƒκΉλ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ 3μœ„κ°€ 3λͺ…이라면, 1,2,3,3,3,6,7,8, ... μ΄λ ‡κ²Œ μˆœμœ„κ°€ λ§€κ²¨μ§‘λ‹ˆλ‹€.

 

RANK() 문법

MySQLκ³Ό Oracle의 RANK() ν•¨μˆ˜ 문법은 각각 μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

MySQL 

RANK() OVER (
	PARTITION BY <expression>[{,<expression>...}]
	ORDER BY <expression> [ASC|DESC], [{,<expression>...}]
)

Oracle

RANK() OVER ([query_partition_clause] order_by_clause)
  • PARTITION BY | query_partition_clause : κ²°κ³Ό 집합을 νŒŒν‹°μ…˜μœΌλ‘œ λ‚˜λˆ•λ‹ˆλ‹€.
    • μ˜΅μ…˜ 값이며, μƒλž΅ν•  경우 쑰회 결과의 λͺ¨λ“  행을 ν•˜λ‚˜μ˜ νŒŒν‹°μ…˜μœΌλ‘œ μ·¨κΈ‰ν•©λ‹ˆλ‹€.
  • ORDER BY | order_by_clause : ν•˜λ‚˜ μ΄μƒμ˜ μ—΄μ΄λ‚˜ ν‘œν˜„μ‹μ„ κΈ°μ€€μœΌλ‘œ νŒŒν‹°μ…˜ λ‚΄μ˜ 행을 μ •λ ¬ν•©λ‹ˆλ‹€.
    • ν•„μˆ˜ 값이며, ν•¨μˆ˜κ°€ μ μš©λ˜λŠ” 각 νŒŒν‹°μ…˜μ˜ ν–‰μ˜ 논리적인 μ •λ ¬ μˆœμ„œλ₯Ό κ²°μ •ν•©λ‹ˆλ‹€.

 

2. DENSE_RANK() ν•¨μˆ˜

[MySQL Tutorial]
DENSE_RANK() ν•¨μˆ˜λŠ” μˆœμœ„ 값에 차이 없이 νŒŒν‹°μ…˜ λ˜λŠ” κ²°κ³Ό μ§‘ν•© λ‚΄μ˜ 각 행에 μˆœμœ„λ₯Ό ν• λ‹Ήν•˜λŠ” μœˆλ„μš° ν•¨μˆ˜μž…λ‹ˆλ‹€.
ν–‰μ˜ μˆœμœ„λŠ” ν–‰ μ•žμ— μ˜€λŠ” κ³ μœ ν•œ μˆœμœ„ κ°’μ—μ„œ 1μ”© μ¦κ°€ν•©λ‹ˆλ‹€.

[Oracle Tutorial]
DENSE_RANK() ν•¨μˆ˜λŠ” μ •λ ¬λœ ν–‰ μ§‘ν•©μ—μ„œ ν–‰μ˜ μˆœμœ„λ₯Ό κ³„μ‚°ν•˜λŠ” 뢄석 ν•¨μˆ˜μž…λ‹ˆλ‹€.
RANK() ν•¨μˆ˜μ™€ 달리 DENSE_RANK() ν•¨μˆ˜λŠ” μˆœμœ„ 값을 μ—°μ†λœ μ •μˆ˜λ‘œ ν• λ‹Ήν•©λ‹ˆλ‹€. 동λ₯ μΈ κ²½μš°μ—λŠ” μˆœμœ„λ₯Ό κ±΄λ„ˆλ›°μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
μˆœμœ„ κΈ°μ€€ 값이 λ™μΌν•œ ν–‰μ—λŠ” λ™μΌν•œ μˆœμœ„ 값이 μ μš©λ©λ‹ˆλ‹€. 

 

DENSE_RANK() ν•¨μˆ˜λŠ” RANK() ν•¨μˆ˜μ™€ λ™μΌν•˜κ²Œ λ™μΌν•œ 값을 κ°€μ§„ 행에 λŒ€ν•΄ λ™μΌν•œ μˆœμœ„λ₯Ό λΆ€μ—¬ν•˜μ§€λ§Œ κ·Έ λ‹€μŒμ— λ‚˜μ˜€λŠ” ν–‰μ—λŠ” μˆœμœ„λ₯Ό κ±΄λ„ˆλ›°μ§€ μ•Šκ³  μ΄μ–΄μ„œ μˆœμœ„λ₯Ό λΆ€μ—¬ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ 3μœ„κ°€ 3λͺ…이라면, 1,2,3,3,3,4,5,6, ... μ΄λ ‡κ²Œ μˆœμœ„κ°€ λ§€κ²¨μ§‘λ‹ˆλ‹€.

DENSE_RANK() 문법

MySQLκ³Ό Oracle의 DENSE_RANK() ν•¨μˆ˜ 문법은 각각 μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

MySQL 

DENSE_RANK() OVER (
    PARTITION BY partition_expression
    ORDER BY sort_expression [ASC|DESC]
)

Oracle

DENSE_RANK( ) OVER([ query_partition_clause ] order_by_clause)

 

PARTITION BY | query_partition_clause κ³Ό ORDER BY | order_by_clauseλŠ” RANK() ν•¨μˆ˜μ—μ„œμ˜ μ„€λͺ…κ³Ό κ°™μŠ΅λ‹ˆλ‹€.

DENSE_RANK()λŠ” νŒŒν‹°μ…˜μ— λ™μΌν•œ μˆœμœ„ 값을 κ°€μ§„ 두 개 μ΄μƒμ˜ 행이 μžˆλŠ” 경우, 각 행에 동일 μˆœμœ„κ°€ λΆ€μ—¬λ˜κ³ , RANK()ν•¨μˆ˜μ™€λŠ” 달리 항상 μ—°μ†λœ μˆœμœ„ 값을 ν• λ‹Ή ν•©λ‹ˆλ‹€. (동일 μˆœμœ„κ°€ μžˆλ‹€ν•˜λ”λΌλ„)

 

3. ROW_NUMBER() ν•¨μˆ˜

[MySQL Tutorial]
ROW_NUMBER() ν•¨μˆ˜λŠ” κ²°κ³Ό μ§‘ν•©μ˜ 각 행에 일련 번호λ₯Ό ν• λ‹Ήν•˜λŠ” μœˆλ„μš° ν•¨μˆ˜ ν˜Ήμ€ 뢄석 ν•¨μˆ˜μž…λ‹ˆλ‹€.
첫번째 μˆ«μžλŠ” 1둜 μ‹œμž‘ν•©λ‹ˆλ‹€.


[Oracle Tutorial]
ROW_NUMBER() ν•¨μˆ˜λŠ” μ μš©λ˜λŠ” 각 ν–‰(νŒŒν‹°μ…˜μ˜ 각 ν–‰ λ˜λŠ” κ²°κ³Ό μ§‘ν•©μ˜ 각 ν–‰)에 순차적으둜 κ³ μœ ν•œ μ •μˆ˜λ₯Ό ν• λ‹Ήν•˜λŠ” 뢄석 ν•¨μˆ˜μž…λ‹ˆλ‹€.

 

ROW_NUMBER() ν•¨μˆ˜λŠ” κ²°κ³Ό μ§‘ν•© λ‚΄μ˜ 각 행에 고유 번호λ₯Ό ν• λ‹Ήν•©λ‹ˆλ‹€.

RANK()λ‚˜ DENSE_RANK() ν•¨μˆ˜λ³΄λ‹€ 맀우 κ°„λ‹¨ν•©λ‹ˆλ‹€.

ROW_NUMBER() ν•¨μˆ˜λŠ” 각 행에 μˆœμœ„λ₯Ό λΆ€μ—¬ν•  λ•Œ λ™μΌν•œ 값이 μžˆμ–΄λ„ 이λ₯Ό λ¬΄μ‹œν•˜κ³  연속적인 μˆœμœ„λ₯Ό λΆ€μ—¬ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ 3μœ„κ°€ 3λͺ…이라해도, 1,2,3,4,5,6, ... μ΄λ ‡κ²Œ μˆœμœ„κ°€ λ§€κ²¨μ§‘λ‹ˆλ‹€.

 

ROW_NUMBER() 문법

MySQLκ³Ό Oracle의 RANK() ν•¨μˆ˜ 문법은 각각 μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

MySQL 

ROW_NUMBER() OVER (
    PARTITION BY <expression>,[{,<expression>}...]
    ORDER BY <expression> [ASC|DESC],[{,<expression>}...]
)

Oracle

ROW_NUMBER() OVER (
   [query_partition_clause] 
   order_by_clause
)

PARTITION BY | query_partition_clause κ³Ό ORDER BY | order_by_clauseλŠ” RANK() ν•¨μˆ˜μ—μ„œμ˜ μ„€λͺ…κ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

4. RANK() vs DENSE_RANK() vs ROW_NUMBER()

μ§€κΈˆκΉŒμ§€ μ•Œμ•„λ³Έ 3κ°€μ§€ μœˆλ„μš° ν•¨μˆ˜μΈ RANK(), DENSE_RANK(), ROW_NUMBER()의 μ‹€μ œ κ²°κ³Όκ°’μ˜ 차이λ₯Ό ν™•μΈν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

학생 정보가 λ‹΄κΈ΄ ν…Œμ΄λΈ”μ„ κ°„λ‹¨ν•˜κ²Œ λ§Œλ“€κ³ , 학생별 ν‰μ μœΌλ‘œ 각 μˆœμœ„ ν•¨μˆ˜μ˜ 차이λ₯Ό ν™•μΈν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

CREATE TABLE `students` (
  `student_id` int NOT NULL,
  `first_name` varchar(50) DEFAULT NULL,
  `last_name` varchar(50) DEFAULT NULL,
  `major` varchar(100) DEFAULT NULL,
  `gpa` decimal(3,2) DEFAULT NULL, // 평점
  PRIMARY KEY (`student_id`)
)

μ λ‹Ήν•œ 데이터λ₯Ό μ—¬λŸ¬κ°œ INSERT ν•œ ν›„ μ•„λž˜ 쿼리λ₯Ό μ‹€ν–‰μ‹œμΌœ λ³΄κ² μŠ΅λ‹ˆλ‹€.

SELECT student_id , first_name , gpa 
		, RANK() OVER (ORDER BY gpa DESC) AS 'RANK'
		, DENSE_RANK () OVER (ORDER BY gpa DESC) AS 'DENSE_RANK'
		, ROW_NUMBER() OVER (ORDER BY gpa DESC, first_name ASC) AS 'ROW_NUM'
FROM students;

μ‹€ν–‰μ‹œν‚¨ κ²°κ³ΌλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

student_id first_name gpa RANK DENSE_ RANK ROW_NUM
3 예린 3.95 1 1 1
2 λ―Όμ§€ 3.90 2 2 2
8 μ§€μš° 3.90 2 2 3
6 μ†Œλ―Ό 3.85 4 3 4
4 μ§€ν˜„ 3.85 4 3 5
5 λ―Όμ€€ 3.80 6 4 6
10 영희 3.80 6 4 7
9 μŠΉν˜„ 3.75 8 5 8
7 μ€€ν˜Έ 3.75 8 5 9
1 민수 3.7 10 6 10

 

3,4번 행을 보면, 3번 ν–‰μ˜ μ§€μš°μ™€ 4번 ν–‰μ˜ μ†Œλ―Όμ΄μ˜ μˆœμœ„ 값이 각 ν•¨μˆ˜λ³„λ‘œ λ‹€λ₯Έ 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

그리고 각 ν•¨μˆ˜λ³„λ‘œ μˆœμœ„λ„ λ‹€λ₯΄κ²Œ λ§€κ²¨μ§€λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

  • RANK: 1 β­’ 2 β­’ 4 β­’ 6 β­’ 8 β­’ 10
  • DENSE_RANK: 1 β­’ 2 β­’ 3 β­’ 4 β­’ 5 β­’ 6
  • ROW_NUM: 1 β­’ 2 β­’ 3 β­’ 4 β­’ 5 β­’ 6 β­’ 7 β­’ 8 β­’ 9 β­’ 10

 

5. PARTITION BY  문법

μΆ”κ°€λ‘œ μ„Έκ°€μ§€ ν•¨μˆ˜μ—μ„œ λͺ¨λ‘ μ˜΅μ…˜ κ°’μœΌλ‘œ μ‚¬μš©λ˜λŠ” νŒŒν‹°μ…˜ ꡬ문에 λŒ€ν•œ μ‚¬μš©λ²•μ„ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

PARTITION BYλŠ” κ·Έλ£Ή λ‚΄ μˆœμœ„ 및 그룹별 집계λ₯Ό ꡬ할 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.

SELECT student_id , major , gpa 
	,RANK() OVER (PARTITION BY major ORDER BY gpa DESC) AS 'PARTITION'
FROM STUDENTS;

 

이 μΏΌλ¦¬λŠ” ν•™μƒλ“€μ˜ 전곡(major)λ³„λ‘œ ν•™μƒλ“€μ˜ 평점(gpa)μˆœμœ„λ₯Ό λ§€κΉλ‹ˆλ‹€.

  • PARTITION BY major ORDER BY gpa DESC: major 컬럼이 같은 행을 그룹으둜 λ¬Άμ–΄μ„œ, κ·Έλ£Ή λ‚΄ gpa 컬럼의 μˆœμœ„λ₯Ό λ‚΄λ¦Όμ°¨μˆœ(DESC)으둜 μ •λ ¬

μœ„ 쿼리λ₯Ό μ‹€ν–‰ν•œ κ²°κ³ΌλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€.

student_id major gpa PARTITION
1 κ²½μ˜ν•™ 3.6 1
8 κ²½μ˜ν•™ 3.5 2
7 κ²½μ˜ν•™ 3.45 3
4 κ²½μ˜ν•™ 3.4 4
9 생물학 3.2 1
6 생물학 3.05 2
3 심리학 3.85 1
5 심리학 3.85 1
2 심리학 3.75 3
10 심리학 3.55 4

 


마치며,

μœˆλ„μš° ν•¨μˆ˜ 쀑 ν•˜λ‚˜μΈ μˆœμœ„ ν•¨μˆ˜μ— λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

μ½”λ”©ν…ŒμŠ€νŠΈλ₯Ό ν•˜λ©΄μ„œ RANK() ν•¨μˆ˜λ₯Ό ν™œμš©ν•΄μ•Όν•˜λŠ” 쿼리λ₯Ό μ œλŒ€λ‘œ μž‘μ„±ν•˜μ§€ λͺ»ν•΄ λ‹€μ‹œ κ³΅λΆ€ν•˜λ©΄μ„œ μ •λ¦¬ν•˜λ‹ˆ 전에 κ³΅λΆ€ν–ˆλ˜ λ‚΄μš©μ΄ λ‹€μ‹œ μƒκ°λ‚˜κΈ°λ„ ν•˜κ³  μƒˆλ‘­κ²Œ λ‹€μ‹œ λ°°μš°κΈ°λ„ ν–ˆμŠ΅λ‹ˆλ‹€.

κ΄€λ ¨ν•œ λ‹€λ₯Έ ν•¨μˆ˜λ“€λ„ 많이 μžˆμœΌλ‹ˆ, λ‹€μŒμ—λŠ” 이외 ν•¨μˆ˜λ“€λ„ μ •λ¦¬ν•˜λŠ” μ‹œκ°„μ„ κ°€μ Έλ³΄μ•„μ•Όκ² μŠ΅λ‹ˆλ‹€ :)

 

참고 링크

 

A Guide to MySQL RANK Funtion By Practical Examples

This tutorial introduces to the MySQL RANK function and how to apply it to assign the rank to each row within the partition of a result set.

www.mysqltutorial.org

 

Oracle RANK() Function By Practical Examples

In this tutorial, you will learn how to use Oracle RANK() function to calculate the rank of rows within a set of rows.

www.oracletutorial.com

πŸ“ŒμΈν„°νŽ˜μ΄μŠ€μ™€ μΆ”μƒν΄λž˜μŠ€μ˜ 차이

  μΈν„°νŽ˜μ΄μŠ€(Interface) 좔상 클래슀(Abstract Class)
μ‚¬μš© λͺ©μ  ν΄λž˜μŠ€κ°€ κ΅¬ν˜„ν•΄μ•Όν•  λ©”μ„œλ“œμ˜ 집합을 μ •μ˜ 상속을 톡해 곡톡 κΈ°λŠ₯ 곡유
κ΅¬ν˜„ λͺ¨λ“  λ©”μ„œλ“œκ°€ 좔상 λ©”μ„œλ“œ (좔상 λ©”μ„œλ“œλ§Œ κ°€λŠ₯) 좔상 λ©”μ„œλ“œμ™€ 일반 λ©”μ„œλ“œλ₯Ό λͺ¨λ‘ 가짐
멀버 λ³€μˆ˜ (μ•”λ¬΅μ μœΌλ‘œ) public static final μΈμŠ€ν„΄μŠ€ λ³€μˆ˜ κ°€μ§ˆ 수 있음
닀쀑 상속 μ—¬λΆ€ ν•˜λ‚˜μ˜ ν΄λž˜μŠ€μ—μ„œ μ—¬λŸ¬κ°œμ˜ μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„ κ°€λŠ₯ ν•˜λ‚˜μ˜ ν΄λž˜μŠ€μ— ν•˜λ‚˜μ˜ 좔상 클래슀만 상속 κ°€λŠ₯
 μƒμ„±μž κ°€λŠ₯μ—¬λΆ€ μƒμ„±μž κ°€μ§ˆ 수 μ—†μŒ μƒμ„±μž κ°€μ§ˆ 수 있음 

 


μžλ°”μ—λŠ” λΉ„μŠ·ν•œ λ“― λ‹€λ₯Έ μΈν„°νŽ˜μ΄μŠ€μ™€ 좔상 ν΄λž˜μŠ€κ°€ μžˆλ‹€. 이 λ‘˜μ˜ 차이점을 정리해보렀 ν•œλ‹€. 

λ¨Όμ €, μΈν„°νŽ˜μ΄μŠ€μ™€ 좔상 ν΄λž˜μŠ€κ°€ 무엇인지 λ¨Όμ € μ•Œμ•„λ³΄μž.

μΈν„°νŽ˜μ΄μŠ€(Interface)

μΈν„°νŽ˜μ΄μŠ€λŠ” λͺ¨λ“  λ©”μ„œλ“œκ°€ 좔상 λ©”μ„œλ“œλ‘œ κ΅¬μ„±λ˜μ–΄μžˆκ³ , ν΄λž˜μŠ€κ°€ κ΅¬ν˜„ν•΄μ•Όν•  λ©”μ„œλ“œμ˜ 집합을 μ •μ˜ν•œλ‹€.

κ°„λ‹¨ν•˜κ²Œ 무언가 κ΅¬ν˜„ν•΄μ•Όν•  λ‚΄μš©μ„ μ •μ˜ν•΄λ†“μ€ 것이라고 μƒκ°ν•˜λ©΄ λœλ‹€.

'κ΅¬ν˜„ν•΄μ•Όν• ' 것듀을 μ •μ˜ν•΄λ†“μ€ κ²ƒμ΄λ―€λ‘œ 일반 ν΄λž˜μŠ€μ™€ 달리 λ©”μ„œλ“œμ— μ½”λ“œ λΈ”λŸ­μ΄ μ—†λ‹€. 즉, μ–΄λ–€ λ©”μ„œλ“œμ˜ κΈ°λŠ₯을 κ΅¬ν˜„ν•΄λ†“μ€ λ‚΄μš©μΈ μ½”λ“œ λΈ”λŸ­μ΄ μ—†λ‹€.

interface μΈν„°νŽ˜μ΄μŠ€λͺ…() {
    public static final μƒμˆ˜λͺ… = κ°’;
    public abstract void λ©”μ„œλ“œλͺ…();
}

μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ„ μ–Έν•  λ•ŒλŠ” μ ‘κ·Ό μ œμ–΄μžμ™€ ν•¨κ»˜ β‘  interface ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

그리고 β‘‘ μΈν„°νŽ˜μ΄μŠ€μ˜ λͺ¨λ“  λ©”μ„œλ“œλŠ” μ•”λ¬΅μ μœΌλ‘œ public 이며, ν•„λ“œ(λ³€μˆ˜)λŠ” public static final 이닀.

*μΈν„°νŽ˜μ΄μŠ€ ν•„λ“œμ— int COUNT = 3;은 public static final을 μƒλž΅ν•΄λ„ μžλ™μœΌλ‘œ public static final이 μ μš©λœλ‹€.

 

λ©”μ„œλ“œμ— κΈ°λŠ₯을 κ΅¬ν˜„ν•΄λ†“μ§€ μ•ŠκΈ° λ•Œλ¬Έμ—, μΈν„°νŽ˜μ΄μŠ€λŠ” ν˜Όμžμ„œ λ¬΄μ–Έκ°ˆ ν•  μˆ˜λŠ” μ—†λ‹€. μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ†ν•œ 클래슀(κ΅¬ν˜„μ²΄)μ—μ„œ λ©”μ„œλ“œλ₯Ό Override ν•΄μ„œ κ΅¬ν˜„ν•΄μ•Όν•œλ‹€.

interface Computer { }
Computer C = new Computer(); // Error: Cannot instantiate the type Computer

μœ„μ²˜λŸΌ μΈν„°νŽ˜μ΄μŠ€κ°€ μžˆλ‹€κ³  ν• λ•Œ, Computer 객체λ₯Ό μƒμ„±ν•˜λ €ν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. 

 

그리고 μΈν„°νŽ˜μ΄μŠ€λŠ” β‘’ 닀쀑 상속이 κ°€λŠ₯ν•΄μ„œ, μ•„λž˜μ™€ 같이 ν•œ ν΄λž˜μŠ€κ°€ μ—¬λŸ¬ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 상속받아 κ΅¬ν˜„ν•  수 μžˆλ‹€.

class 클래슀λͺ… implements μΈν„°νŽ˜μ΄μŠ€1, μΈν„°νŽ˜μ΄μŠ€2

 

β‘£ Java8 λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€λŠ” default λ©”μ„œλ“œμ™€ static λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

μΈν„°νŽ˜μ΄μŠ€μ˜ λ©”μ„œλ“œλŠ” κ΅¬ν˜„μ²΄λ₯Ό κ°€μ§ˆ 수 μ—†μ§€λ§Œ, default λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μ‹€μ œ κ΅¬ν˜„λœ ν˜•νƒœμ˜ λ©”μ„œλ“œλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€. 

그리고 μΈν„°νŽ˜μ΄μŠ€μ— static λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜λ©΄ μΈν„°νŽ˜μ΄μŠ€λͺ….μŠ€νƒœν‹±λ©”μ„œλ“œλͺ…κ³Ό 같이 μ‚¬μš©ν•˜μ—¬ 일반 클래슀의 static λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 것과 λ™μΌν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€.

interface TestInterface {
    // default λ©”μ„œλ“œ
    default void printSomething() {
    	System.out.println("default method in interface");
    }
    // static λ©”μ„œλ“œ
    static int getNum() {
    	return 10;
    }
}

μ•„λž˜μ™€ 같이 μΈν„°νŽ˜μ΄μŠ€λͺ….μŠ€νƒœν‹±λ©”μ„œλ“œλͺ…μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.

TestInterface.printSomething();

 

μΈν„°νŽ˜μ΄μŠ€(Interface)λ₯Ό μ‚¬μš©ν•˜λŠ” 이유?

κ·Έλ ‡λ‹€λ©΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ™œ μ‚¬μš©ν•΄μ•Ό ν•˜λŠ”κ±ΈκΉŒ?

보톡 μ€‘μš” 클래슀λ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ—μ„œ 클래슀의 κ΅¬ν˜„μ²΄κ°€ λͺ‡ κ°œκ°€ 될지 μ•Œ 수 μ—†μœΌλ―€λ‘œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•΄μ„œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κΈ°μ€€μœΌλ‘œ λ©”μ„œλ“œλ₯Ό λ§Œλ“œλŠ” 것이 효율적이기 λ•Œλ¬Έμ΄λ‹€.

 

λ‹Ήμž₯ 이 λ¬Έμž₯을 μ½μ—ˆμ„λ•ŒλŠ” 무슨 μ†Œλ¦°κ°€ μ‹Άλ‹€.

 

μ˜ˆμ‹œλ‘œ ν•œλ²ˆ λ‹€μ‹œ μ •λ¦¬ν•΄λ³΄μž.

Animal 클래슀λ₯Ό μƒμ†ν•˜λŠ” Tiger, Bear ν΄λž˜μŠ€κ°€ 있고, 이듀을 κ΄€λ¦¬ν•˜κ³  먹이λ₯Ό μ£ΌλŠ” ZooKeeper ν΄λž˜μŠ€κ°€ μžˆλ‹€κ³  ν•΄λ³΄μž.

class Animal {
	String name;
	void setName(String name) {
		this.name = name;
	}
}

class Tiger extends Animal { }
class Bear extends Animal { }
class ZooKeeper {
	void feed(Tiger tiger) {
		System.out.println("feed apple to Tiger");
	}
	void feed(Bear bear) {
		System.out.println("feed banana to Bear");
	}
}

ZooKeeperλŠ” feed() λ©”μ„œλ“œ ν˜ΈμΆœμ‹œ 인자의 νƒ€μž…μ— 따라 Tigerλ‚˜ Bearμ—κ²Œ 먹이λ₯Ό μ€€λ‹€.

public static void main(String[] args) {
    ZooKeeper zooKeeper = new ZooKeeper();
    Tiger tiger = new Tiger();
    Bear bear = new Bear();

    zooKeeper.feed(tiger); // feed apple to Tiger
    zooKeeper.feed(bear); // feed banana to Bear
}

근데 μ΄λ•Œ 동물듀이 κ³„μ†ν•΄μ„œ λŠ˜μ–΄λ‚œλ‹€λ©΄, ZooKeeper에 ν•΄λ‹Ή λ™λ¬Όλ“€μ˜ νƒ€μž…μ„ λ§€κ°œλ³€μˆ˜λ‘œ ν•œ feed() λ©”μ„œλ“œλ₯Ό 계속 계속 μΆ”κ°€ν•΄μ£Όμ–΄μ•Όν•œλ‹€. μ΄λ ‡κ²Œ 계속 μΆ”κ°€ν•˜κ²Œ 되면 ZooKeeper κ°€ ꡉμž₯히 λ³΅μž‘ν•΄μ§ˆ 것이닀.

 

μ΄λŸ΄λ•Œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λ©΄ 훨씬 효율적으둜 μ½”λ“œλ₯Ό ꡬ성할 수 μžˆλ‹€.

먹이λ₯Ό μ£ΌλŠ” λ©”μ„œλ“œ κΈ°λŠ₯을 κ°€μ§„ μΈν„°νŽ˜μ΄μŠ€ Workλ₯Ό μƒμ„±ν•΄λ³΄μž.

interface Work {	} // μΈν„°νŽ˜μ΄μŠ€
class Animal { // λΆ€λͺ¨(μƒμœ„) 클래슀
    String name;
    void setName(String name) {
    	this.name = name;
    }
}
class Tiger extends Animal implements Work { }
class Bear extends Animal implements Work { }

그리고 Tiger, Bear ν΄λž˜μŠ€μ—μ„œ  μΈν„°νŽ˜μ΄μŠ€ Workλ₯Ό μƒμ†ν•œλ‹€. 

*μΈν„°νŽ˜μ΄μŠ€ μƒμ†μ‹œ ν‚€μ›Œλ“œλŠ” implements

 

μ΄λ ‡κ²Œν•˜λ©΄ ZooKeeper ν΄λž˜μŠ€μ— μΈν„°νŽ˜μ΄μŠ€ Work νƒ€μž…μ„ λ§€κ°œλ³€μˆ˜λ‘œ λ°›μ•„μ„œ 먹이λ₯Ό μ£ΌλŠ” κΈ°λŠ₯인 feed() λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€. 

class ZooKeeper {
    void feed(Work work) {
        System.out.println("feed apple to Animal");
    }
}

μ›λž˜λŠ” Tiger, Bear νƒ€μž…μ— λŒ€ν•΄ 각각 feed() λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•΄μ•Όν–ˆμ§€λ§Œ, μΈν„°νŽ˜μ΄μŠ€μΈ Work νƒ€μž…μ˜ν•˜λ‚˜μ˜ λ©”μ„œλ“œλ§ŒμœΌλ‘œλ„ feed() λ©”μ„œλ“œ κ΅¬ν˜„μ΄ κ°€λŠ₯ν•˜λ‹€.

μ‹€μ œλ‘œ Tiger, Bear μΈμŠ€ν„΄μŠ€λ₯Ό feed(Work work) λ©”μ„œλ“œμ˜ 인자둜 λ„£μ–΄μ„œ ν˜ΈμΆœν•˜λ©΄ μ•„λž˜μ™€ 같은 κ²°κ³Όκ°€ λ‚˜μ˜¨λ‹€.

public static void main(String[] args) {
    ZooKeeper zooKeeper = new ZooKeeper();
    Tiger tiger = new Tiger();
    Bear bear = new Bear();

    zooKeeper.feed(tiger); // feed apple to Animal
    zooKeeper.feed(bear); // feed apple to Animal
}

 

이제 μ–΄λ–€ 동물 클래슀λ₯Ό μΆ”κ°€ν•˜λ“  ZooKeeper ν΄λž˜μŠ€μ— feed() λ©”μ„œλ“œλ₯Ό μΆ”κ°€ν•  ν•„μš”κ°€ μ—†λ‹€.

 

λ‹€μ‹œ μœ„μ—μ„œ μ–˜κΈ°ν–ˆλ˜ 이유λ₯Ό κ°€μ Έμ˜€λ©΄,

"μ€‘μš” 클래슀λ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ—μ„œ 클래슀의 κ΅¬ν˜„μ²΄κ°€ λͺ‡ κ°œκ°€ 될지 μ•Œ 수 μ—†μœΌλ―€λ‘œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•΄μ„œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κΈ°μ€€μœΌλ‘œ λ©”μ„œλ“œλ₯Ό λ§Œλ“œλŠ” 것이 효율적"

μ΄λΌλŠ” 말이 μ‘°κΈˆμ€ 이해가 될 것이닀.

 

λ‹€λ§Œ, μœ„ μ˜ˆμ‹œλŠ” μΈν„°νŽ˜μ΄μŠ€κ°€ μ™œ ν•„μš”ν•œκ°€μ— λŒ€ν•œ 뢀뢄에 λŒ€ν•œ μ„€λͺ…을 μœ„ν•œ μ˜ˆμ‹œλ‘œ, Work μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ†ν•˜λŠ” λͺ¨λ“  ν΄λž˜μŠ€μ—μ„œ 같은 좜λ ₯이 λ‚˜μ˜¨λ‹€. 이건 Work μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ†λ°›λŠ” ν•˜μœ„ 클래슀, 즉 μžμ‹ ν΄λž˜μŠ€μ—μ„œ λ³„λ„λ‘œ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•΄μ„œ 각 동물 ν΄λž˜μŠ€λ§ˆλ‹€ λ‹€λ₯Έ κ²°κ³Όλ₯Ό λ‚˜μ˜€κ²Œ ν•  수 μžˆλ‹€.

*μ–΄λ–»κ²Œ ν•˜λŠ”κ±΄μ§€λŠ” 이 ν¬μŠ€νŒ…μ—μ„œλŠ” 닀루지 μ•Šκ² λ‹€. 좔상 ν΄λž˜μŠ€λž‘ 비ꡐ가 λͺ©μ μ΄λ―€λ‘œ..

 

좔상 클래슀(Abstract Class)

좔상 ν΄λž˜μŠ€λŠ” β‘  ν•˜λ‚˜ μ΄μƒμ˜ 좔상 λ©”μ„œλ“œλ₯Ό ν¬ν•¨ν•˜λ©°, μΈν„°νŽ˜μ΄μŠ€μ˜ 역할도 ν•˜λ©΄μ„œ 클래슀의 κΈ°λŠ₯도 κ°€μ§€κ³  μžˆλŠ” ν΄λž˜μŠ€μ΄λ‹€. 

ν•˜λ‚˜ μ΄μƒμ˜ 좔상 λ©”μ„œλ“œλ₯Ό ν¬ν•¨ν•œλ‹€λŠ” 것은, 일반 λ©”μ„œλ“œλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€λŠ” μ˜λ―Έλ„ λ‚΄ν¬ν•œλ‹€.

μΈν„°νŽ˜μ΄μŠ€μ˜ 경우, λͺ¨λ“  λ©”μ„œλ“œκ°€ 좔상 λ©”μ„œλ“œμΈ 반면 좔상 ν΄λž˜μŠ€λŠ” 미리 κ΅¬ν˜„λœ λ©”μ„œλ“œλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€λŠ” 차이가 μžˆλ‹€.

abstract class 클래슀λͺ…() { // 좔상 클래슀
    abstract λ°˜ν™˜νƒ€μž… λ©”μ„œλ“œλͺ…(); // 좔상 λ©”μ„œλ“œ
}

좔상 λ©”μ„œλ“œλŠ” μΈν„°νŽ˜μ΄μŠ€μ˜ λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ κ΅¬ν˜„μ²΄κ°€ μ—†λ‹€.

즉, 좔상 클래슀λ₯Ό μƒμ†ν•˜λŠ” μžμ‹ ν΄λž˜μŠ€μ—μ„œ λ°˜λ“œμ‹œ ν•΄λ‹Ή 좔상 λ©”μ„œλ“œλ₯Ό μ˜€λ°”λΌμ΄λ”©μ„ν•΄μ•Ό μ‚¬μš©ν•  수 μžˆλ‹€.

좔상 λ©”μ„œλ“œλŠ” μ½”λ“œ λΈ”λŸ­μ΄ μžˆλŠ” κ΅¬ν˜„μ²΄λ‘œ μž‘μ„±λ˜μ§€ μ•Šκ³ , μ„ μ–ΈλΆ€λ§Œ μ‘΄μž¬ν•œλ‹€. 이 λ©”μ„œλ“œλ₯Ό μžμ‹ ν΄λž˜μŠ€μ—μ„œ μ˜€λ²„λΌμ΄λ”©ν•˜μ—¬ κ΅¬ν˜„ν•΄μ„œ μ‚¬μš©ν•˜λŠ” 것이닀.

 

λ‹€μ‹œλ§ν•΄, 좔상 ν΄λž˜μŠ€λŠ” "λ‚΄κ°€ 이 κΈ°λŠ₯을 정해두지 μ•Šμ„ν…Œλ‹ˆ, λ‚˜λ₯Ό μƒμ†ν•œ μžμ‹ ν΄λž˜μŠ€λ“€μ•„, λ‚΄κ°€ μ •μ˜ν•œ κΈ°λŠ₯을 κ΅¬ν˜„ν•΄λ΄!" 라고 이야기 ν•˜λŠ” 것이닀. 여기에 μΆ”κ°€λ‘œ, "단 μΌλΆ€λŠ” λ§Œλ“€μ–΄μ£Όκ³ , μΌλΆ€λŠ” μ•ˆλ§Œλ“€μ–΄μ€„κ²Œ" 라고 ν•œλ‹€κ³  μƒκ°ν•˜λ©΄ κΈ°μ–΅ν•˜κΈ° 쉽닀.

 

좔상 ν΄λž˜μŠ€λŠ” μΈν„°νŽ˜μ΄μŠ€μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ κ΅¬ν˜„λΆ€κ°€ μ—†λŠ” 좔상 λ©”μ„œλ“œκ°€ 있기 λ•Œλ¬Έμ— 일반 ν΄λž˜μŠ€μ™€ 달리  β‘‘ λ‹¨λ…μœΌλ‘œ 객체, 즉 μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μ—†λ‹€.

λ°˜λ“œμ‹œ 좔상 클래슀λ₯Ό μƒμ†ν•œ μ‹€μ œ 클래슀λ₯Ό ν†΅ν•΄μ„œλ§Œ 객체λ₯Ό 생성할 수 μžˆλ‹€.

(좔상 클래슀λ₯Ό μƒμ†ν•œ μžμ‹ ν΄λž˜μŠ€μ—μ„œ ν•΄λ‹Ή 좔상 클래슀의 좔상 λ©”μ„œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”© ν•΄μ•Ό, μžμ‹ 클래슀의 μΈμŠ€ν„΄μŠ€ 생성 κ°€λŠ₯)

abstract class Teacher { }
Teacher t = new Teacher();  // Error: Cannot instantiate the type Teacher

 

그리고 좔상 ν΄λž˜μŠ€λŠ” μΈν„°νŽ˜μ΄μŠ€μ™€ 달리 일반 클래슀처럼 β‘’ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜, μƒμ„±μž, private λ©”μ„œλ“œ 등을 κ°€μ§ˆ 수 μžˆλ‹€.

즉, 좔상 λ©”μ„œλ“œμ™€ 일반 λ©”μ„œλ“œ, 객체 λ³€μˆ˜, μƒμ„±μžκΉŒμ§€ κ°€μ§ˆ 수 μžˆλŠ” 것이닀.

abstract class Teacher {
	private String name; // 멀버 λ³€μˆ˜
	Teacher() {} // μƒμ„±μž
    
	abstract void hello(); // 좔상 λ©”μ„œλ“œ
	void hi() { System.out.println("μ•ˆλ…•!"); } // 일반 λ©”μ„œλ“œ
}

 

그리고 Javaμ—μ„œλŠ” 클래슀의 닀쀑 상속을 막기 λ•Œλ¬Έμ— β‘£ 좔상 ν΄λž˜μŠ€λŠ” 닀쀑 상속을 ν•  수 μ—†λ‹€.

class 클래슀λͺ… extends μΆ”μƒν΄λž˜μŠ€

 

좔상 클래슀(Abstract Class)λ₯Ό μ‚¬μš©ν•˜λŠ” 이유?

좔상 λ©”μ„œλ“œλ„ μΈν„°νŽ˜μ΄μŠ€μ™€ λΉ„μŠ·ν•˜κ²Œ, μ€‘λ³΅λ˜κ±°λ‚˜ κ³΅ν†΅λ˜λŠ” 뢀뢄에 λŒ€ν•΄ 미리 λ§Œλ“€μ–΄μ§„ 것을 μ‚¬μš©ν•˜κ³ , 이λ₯Ό μ‚¬μš©ν•˜λŠ” μͺ½μ—μ„œ μžμ‹ μ—κ²Œ ν•„μš”ν•œ λΆ€λΆ„λ§Œ μž¬μ •μ˜ν•΄μ„œ μ‚¬μš©ν•¨μœΌλ‘œμ¨ 생산성과 νš¨μœ¨μ„±μ΄ ν–₯μƒλ˜κΈ° λ•Œλ¬Έμ— μ‚¬μš©ν•œλ‹€.

 

λ˜ν•œ 좔상 λ©”μ„œλ“œκ°€ ν¬ν•¨λœ 클래슀λ₯Ό μƒμ†λ°›λŠ” ν•˜μœ„(μžμ‹)ν΄λž˜μŠ€κ°€ λ°˜λ“œμ‹œ κ·Έ 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜κ²Œλ” ν•˜κΈ° μœ„ν•¨μ΄λ‹€.

일반 λ©”μ„œλ“œλŠ” ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šμ„μˆ˜λ„ μžˆμ§€λ§Œ, 좔상 λ©”μ„œλ“œκ°€ ν¬ν•¨λœ 좔상 클래슀λ₯Ό 상속받은 λͺ¨λ“  ν•˜μœ„(μžμ‹)ν΄λž˜μŠ€λŠ” 좔상 λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•΄μ•Όλ§Œ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 있기 λ•Œλ¬Έμ— λ°˜λ“œμ‹œ κ΅¬ν˜„ν•˜κ²Œ λœλ‹€.

 

μΈν„°νŽ˜μ΄μŠ€(Interface) vs 좔상 클래슀(Abstract Class)

그럼 이 λ‘˜μ˜ 차이가 어디에 μžˆλŠ”μ§€ μ •λ¦¬ν•΄λ³΄μž.

 

1. μ‚¬μš© λͺ©μ 

  • μΈν„°νŽ˜μ΄μŠ€λŠ” λͺ¨λ“  λ©”μ„œλ“œκ°€ 좔상 λ©”μ„œλ“œλ‘œ, μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ†λ°›λŠ” ν΄λž˜μŠ€κ°€ κ΅¬ν˜„ν•΄μ•Ό ν•  λ©”μ„œλ“œμ˜ 집합을 μ •μ˜ν•œλ‹€. 
  • 좔상 ν΄λž˜μŠ€λŠ” 1개 μ΄μƒμ˜ 좔상 λ©”μ„œλ“œκ°€ 있고, 일반 λ©”μ„œλ“œλ„ 포함할 수 있기 λ•Œλ¬Έμ—, 좔상 λ©”μ„œλ“œμ˜ κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κ²Œ ν•˜κΈ° μœ„ν•΄μ„œλ„ μžˆμ§€λ§Œ, 상속을 ν†΅ν•œ 곡톡 κΈ°λŠ₯ κ³΅μœ ν•˜λ„λ‘ ν•˜λŠ” 것에도 λͺ©μ μ΄ μžˆλ‹€.

2. κ΅¬ν˜„

  • μΈν„°νŽ˜μ΄μŠ€λŠ” λͺ¨λ“  λ©”μ„œλ“œκ°€ 좔상 λ©”μ„œλ“œμ΄λ‹€.
  • 좔상 ν΄λž˜μŠ€λŠ” 좔상 λ©”μ„œλ“œμ™€ 일반 λ©”μ„œλ“œλ₯Ό λͺ¨λ‘ κ°€μ§ˆ 수 μžˆλ‹€.

3. 멀버 λ³€μˆ˜

  • μΈν„°νŽ˜μ΄μŠ€μ˜ 멀버 λ³€μˆ˜λŠ” public static final이닀. 즉, μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ₯Ό κ°€μ§ˆ 수 μ—†λ‹€.
  • 좔상 ν΄λž˜μŠ€λŠ” μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.

4. μƒμ„±μž κ°€λŠ₯ μ—¬λΆ€

  • μΈν„°νŽ˜μ΄μŠ€λŠ” μƒμ„±μžλ₯Ό κ°€μ§ˆ 수 μ—†λ‹€.
  • 좔상 ν΄λž˜μŠ€λŠ” μƒμ„±μžλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.

5. 닀쀑 상속 μ—¬λΆ€

  • μΈν„°νŽ˜μ΄μŠ€(ν‚€μ›Œλ“œ: implements)λŠ” 닀쀑 상속이 κ°€λŠ₯ν•˜λ‹€.
  • 좔상 클래슀(ν‚€μ›Œλ“œ: extends) λŠ” 닀쀑 상속이 λΆˆκ°€λŠ₯ν•˜λ‹€. 

마치며,

Java의 μΈν„°νŽ˜μ΄μŠ€μ™€ 좔상 ν΄λž˜μŠ€μ— λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜λ‹€.

μ•Œμ•„λ³΄λ©΄μ„œλ„ 더 μ•Œμ•„λ΄μ•Όν•  κ°œλ…λ“€μ΄ λ§Žμ•„μ„œ, 이후에 ν•˜λ‚˜μ”© 차근히 정리해보아야겠닀. 

 

μ°Έκ³  ν¬μŠ€νŒ… 및 μ„œμ 

  • Do it! 점프 투 μžλ°”
  • TCP School

단좕 평가(Short-circuit Evaluation)λž€?

단좕 ν‰κ°€λŠ” ν‘œν˜„μ‹μ˜ κ²°κ³Όλ₯Ό κ²°μ •ν•˜λŠ”λ°μ— ν•„μš”ν•œ μ΅œμ†Œν•œμ˜ μ—°μ‚°λ§Œ μˆ˜ν–‰ν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€.

λ‹€λ₯΄κ²Œ λ§ν•˜λ©΄, ν‘œν˜„μ‹μ˜ κ²°κ³Όλ₯Ό κ²°μ •ν•˜λŠ” 도쀑에 κ²°κ³Όκ°€ ν™•μ •λœ 경우, λ‚˜λ¨Έμ§€ 연산을 μˆ˜ν–‰ν•˜μ§€ μ•Šκ³  μƒλž΅ν•˜λŠ” 것을 λ§ν•œλ‹€.

그리고 단좕 ν‰κ°€λŠ” 논리 μ—°μ‚°μ—μ„œ νš¨μœ¨μ„±μ„ λ†’μ΄λŠ” μ€‘μš”ν•œ κ°œλ…μ΄λ‹€.

 

πŸ’‘ ν‘œν˜„μ‹(Expression)

ν‘œν˜„μ‹μ€ 값을 κ³„μ‚°ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” μ½”λ“œμ˜ ν•œ 쑰각으둜, 결과적으둜 ν•˜λ‚˜μ˜ 값을 λ§Œλ“€μ–΄λ‚Έλ‹€.

예λ₯Ό λ“€μ–΄ 10 + 3 은 13μ΄λΌλŠ” 값을 λ§Œλ“€μ–΄λ‚΄λŠ” ν‘œν˜„μ‹μ΄λ‹€.

 

단좕 ν‰κ°€μ˜ 적용

논리 μ—°μ‚°μžμΈ AND(&&)와 OR(||) 연산은 단좕 평가λ₯Ό μˆ˜ν–‰ν•œλ‹€.

논리곱(&&) μ—°μ‚°

논리곱(&&) μ—°μ‚°μžλŠ” 두 ν”Όμ—°μ‚°μžκ°€ λͺ¨λ‘ true 일 λ•Œ, trueλ₯Ό λ°˜ν™˜ν•œλ‹€.

그리고 μ’Œν•­μ—μ„œ μš°ν•­μœΌλ‘œ 평가가 μ§„ν–‰λœλ‹€. 

 

(ν”Όμ—°μ‚°μž 1) && (ν”Όμ—°μ‚°μž 2) κ°€ 있으면 ν”Όμ—°μ‚°μž 1이 λ¨Όμ € ν‰κ°€λ˜κ³ , ν”Όμ—°μ‚°μž 2κ°€ ν‰κ°€λ˜λŠ” 것이닀.

ν”Όμ—°μ‚°μž 1이 true라고 ν•΄μ„œ ν‘œν˜„μ‹ 전체λ₯Ό true둜 평가할 μˆ˜λŠ” μ—†κ³ , ν”Όμ—°μ‚°μž 2κΉŒμ§€ 평가λ₯Ό ν•΄λ³΄μ•„μ•Όν•œλ‹€.

즉, λ‘λ²ˆμ§Έ ν”Όμ—°μ‚°μžμΈ ν”Όμ—°μ‚°μž 2κ°€ 논리곱 μ—°μ‚°μ˜ κ²°κ³Όλ₯Ό κ²°μ •ν•œλ‹€κ³  λ³Ό 수 μžˆλ‹€. 

 

그런데 μ΄λ•Œ ν”Όμ—°μ‚°μž 1이 false 라면, ν”Όμ—°μ‚°μž 2의 κ²°κ³Όμ™€λŠ” 관계없이 논리곱 μ—°μ‚°μ˜ κ²°κ³Όκ°€ falseκ°€ λœλ‹€.

논리곱(&&) 연산은 두 ν”Όμ—°μ‚°μžκ°€ λͺ¨λ‘ trueμ΄μ—¬μ•Όν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

 

논리합(||) μ—°μ‚°

논리합(||) μ—°μ‚°μžλŠ” 두 ν”Όμ—°μ‚°μž 쀑 ν•˜λ‚˜λΌλ„ true 일 λ•Œ, trueλ₯Ό λ°˜ν™˜ν•œλ‹€.

논리곱 μ—°μ‚°μžμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ μ’Œν•­μ—μ„œ μš°ν•­μœΌλ‘œ ν‰κ°€λœλ‹€.

 

(ν”Όμ—°μ‚°μž 1) || (ν”Όμ—°μ‚°μž 2) κ°€ μžˆλ‹€κ³  ν•  λ•Œ, ν”Όμ—°μ‚°μž 1이 true라면 λ‘λ²ˆμ§Έ ν”Όμ—°μ‚°μžμΈ ν”Όμ—°μ‚°μž 2λ₯Ό ν‰κ°€ν•˜μ§€ μ•Šμ•„λ„ 이 ν‘œν˜„μ‹μ΄ true라고 평가할 수 μžˆλ‹€.

그런데 μ΄λ•Œ ν”Όμ—°μ‚°μž 1이 false 라면, ν”Όμ—°μ‚°μž 2λ₯Ό ν‰κ°€ν•΄μ•Όμ§€λ§Œ 이 ν‘œν˜„μ‹μ˜ κ²°κ³Όλ₯Ό ν™•μ •ν•  수 μžˆλ‹€. 

논리합 μ—°μ‚°μžλŠ” λ‘˜ 쀑 ν•˜λ‚˜λΌλ„ trueλ©΄ trueλ₯Ό λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

 

논리곱(&&) μ—°μ‚°μžμ™€ 논리합(||) μ—°μ‚°μžμ˜ 단좕 평가

그럼 논리곱, 논리합 μ—°μ‚°μžμ˜ 단좕 평가가 μ–΄λ–»κ²Œ μ΄λ€„μ§€λŠ”μ§€ μ•Œμ•„λ³΄μž.

 

결둠을 λ§ν•˜μžλ©΄,

논리곱(&&) μ—°μ‚°μžλŠ” 첫번째 ν”Όμ—°μ‚°μžκ°€ false λ©΄, 이후 ν”Όμ—°μ‚°μžμ— λŒ€ν•΄μ„œλŠ” 평가λ₯Ό ν•˜μ§€ μ•Šκ³ ,

논리합(||) μ—°μ‚°μžλŠ” 첫번째 ν”Όμ—°μ‚°μžκ°€ true λ©΄, 이후 ν”Όμ—°μ‚°μžμ— λŒ€ν•΄μ„œλŠ” 평가λ₯Ό ν•˜μ§€ μ•ŠλŠ”λ‹€.

 

λ‹€μŒ 예제둜 μžμ„Ένžˆ μ•Œμ•„λ³΄μž.

1 == 0 : false
1 / 0 == 0 : Error

 

쑰건이 μœ„μ™€ 같이 μžˆλ‹€ν• λ•Œ, 각 κ²°κ³ΌλŠ” 1 == 0 은 false, 1 / 0 == 0 은 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

그럼 λ‘κ°œμ˜ ν”Όμ—°μ‚°μžλ‘œ ν‘œν˜„μ‹μ„ κ΅¬μ„±ν•΄μ„œ 논리곱 연산을 ν•˜λ©΄ μ–΄λ–»κ²Œ 될까?

1 == 0 && 1 / 0 == 0

μœ„ ν‘œν˜„μ‹μ—μ„œ λ‘λ²ˆμ§Έ ν”Όμ—°μ‚°μžμ— 1 / 0 은 μ—λŸ¬κ°€ λ°œμƒν•˜λ―€λ‘œ, μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•Šμ„κΉŒν•˜μ§€λ§Œ, κ²°κ³ΌλŠ” false 이닀!

논리곱(&&) μ—°μ‚°μžλŠ” μ’Œν•­λΆ€ν„° 연산을 ν•˜κ³ , 단좕 평가λ₯Ό ν•˜κΈ° λ•Œλ¬Έμ— 첫번째 ν”Όμ—°μ‚°μžκ°€ false 라면, λ‘λ²ˆμ§Έ ν”Όμ—°μ‚°μžμ— λŒ€ν•΄μ„œλŠ” 평가λ₯Ό ν•˜μ§€ μ•Šκ³  (κ²°κ³Όκ°€ ν™•μ •λ˜μ—ˆκΈ° λ•Œλ¬Έ) false λ₯Ό λ°˜ν™˜ν•œλ‹€. 

λ‘λ²ˆμ§Έ ν”Όμ—°μ‚°μžμ— κ΄€λ ¨λœ μ½”λ“œλŠ” μ‹€ν–‰ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ Dead Codeκ°€ λœλ‹€.

*Dead Code: μ‹€ν–‰λ˜μ§€ μ•ŠλŠ” μ½”λ“œ

 

논리합(||) μ—°μ‚°μžλ„ λ§ˆμ°¬κ°€μ§€λ‘œ λ‹€μŒ 예제둜 μ‚΄νŽ΄λ³΄μž.

1 == 0 || 1 / 0 == 0

μ΄λ•ŒλŠ” 첫번째 ν”Όμ—°μ‚°μžκ°€ false 이고, κ²°κ³Όκ°€ ν™•μ •λ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ 1 / 0 == 0 κΉŒμ§€ 연산을 μˆ˜ν–‰ν•˜κ²Œ λ˜μ–΄μ„œ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

1 == 1 || 1 / 0 == 0

λ§Œμ•½ 첫번째 ν”Όμ—°μ‚°μžκ°€ 1 == 1둜, κ²°κ³Όκ°€ true 라면, λ‘λ²ˆμ§Έ ν”Όμ—°μ‚°μžλ₯Ό ν‰κ°€ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ 결과둜 trueκ°€ λ°˜ν™˜λœλ‹€.

논리합(||) μ—°μ‚°μžλ„ μ’Œν•­λΆ€ν„° 연산을 μˆ˜ν–‰ν•˜κ³  단좕 평가λ₯Ό ν•˜κΈ° λ•Œλ¬Έμ— μ•žμ„  연산이 true 라면 κ²°κ³Όκ°€ ν™•μ •λ˜μ–΄ 이후 연산을 μˆ˜ν–‰ν•˜μ§€ μ•ŠλŠ”λ‹€.

λ§ˆμ°¬κ°€μ§€λ‘œ λ‘λ²ˆμ§Έ ν”Όμ—°μ‚°μžμ— κ΄€λ ¨λœ μ½”λ“œλŠ” μ‹€ν–‰ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ Dead Codeκ°€ λœλ‹€.

 

단좕 평가 κ·œμΉ™

단좕 ν‰κ°€μ˜ κ·œμΉ™μ€ μ•„λž˜ ν‘œμ™€ κ°™λ‹€.

단좕 평가 ν‘œν˜„μ‹ κ²°κ³Ό
true && anything anything
false && anything false
true || anything true
false || anything anything

 

단좕 ν‰κ°€μ˜ 이점

단좕 ν‰κ°€μ˜ 이점은 νš¨μœ¨μ„± ν–₯상에 λ”°λ₯Έ μ„±λŠ₯ ν–₯상에 μžˆλ‹€.

논리 μ—°μ‚° μˆ˜ν–‰μ‹œ κ²°κ³Όκ°€ 이미 κ²°μ •λœ 경우 λ‚˜λ¨Έμ§€ 뢀뢄을 μˆ˜ν–‰ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λΆˆν•„μš”ν•œ 계산을 μƒλž΅ν•˜μ—¬ νš¨μœ¨μ„±μ„ 높인닀. μ΄λŠ” 특히 연산을 많이 μˆ˜ν–‰ν•˜λŠ” λ©”μ„œλ“œλ‚˜ I/O μž‘μ—…μ΄ ν¬ν•¨λœ κ²½μš°μ— 이점이 컀진닀.

boolean result = (condition1 && condition2); // condition1이 false라면 condition2λŠ” ν‰κ°€λ˜μ§€ μ•ŠμŒ

 

그리고 λ‹¨μΆ• ν‰κ°€λŠ” νŠΉμ • μ‘°κ±΄μ—μ„œλ§Œ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ±°λ‚˜ 연산을 μˆ˜ν–‰ν•˜κ³ μž ν•  λ•Œ μœ μš©ν•˜κ²Œ 쓰인닀.

if (obj != null && obj.someMethod()) {
	// objκ°€ null이 μ•„λ‹Œ κ²½μš°μ—λ§Œ obj.someMethod()κ°€ 호좜	
}

 

λ˜ν•œ νŠΉμ • 연산을 μ‹€μ œλ‘œ ν•„μš”ν•œ κ²½μš°μ—λ§Œ μˆ˜ν–‰ν•˜κ²Œλ” ν•œλ‹€.

if (condition && someMethod()) {
	// someMethod()λŠ” condition이 true인 κ²½μš°μ—λ§Œ 호좜
}

 

μ΄λŠ” λ°°μ—΄μ΄λ‚˜ 리슀트 같은 자료 ꡬ쑰λ₯Ό μ ‘κ·Όν•  λ•Œ λ²”μœ„ μ²΄ν¬μ‹œμ—λ„ μœ μš©ν•˜λ‹€.

if (idx < array.length && array[idx] == target) {
	// array[idx]에 μ•ˆμ „ν•œ μ ‘κ·Ό κ°€λŠ₯
}

마치며,

단좕 평가λ₯Ό λͺ¨λ₯Έλ‹€λ©΄ μ½”λ“œ κ΅¬ν˜„μ‹œ μ˜λ„ν•œλŒ€λ‘œ κ²°κ³Όκ°€ λ‚˜μ˜€μ§€ μ•Šκ±°λ‚˜, λŸ°νƒ€μž„ μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” λ“±μ˜ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆκ² λ‹€.

이번 기회λ₯Ό 톡해 단좕 평가λ₯Ό 잘 μ •λ¦¬ν•œ 것 κ°™λ‹€.

그리고 Java μΉ΄ν…Œκ³ λ¦¬λ‘œ λΆ„λ₯˜ν•˜κΈ΄ ν–ˆμ§€λ§Œ, 단좕 ν‰κ°€λŠ” λŒ€λΆ€λΆ„μ˜ μ£Όμš” ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ μ§€μ›ν•œλ‹€κ³  ν•œλ‹€.

 

μ°Έκ³  ν¬μŠ€νŒ…

 

[JavaScript] 단좕 평가

μ˜€λŠ˜μ€ 단좕 평가에 λŒ€ν•΄ μ•Œμ•„λ³΄μž [ 논리 μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•œ 단좕 평가 ] 논리 ν•© (| |) λ˜λŠ” 논리 κ³± (&&) μ—°μ‚°μž ν‘œν˜„μ‹μ€ μ–Έμ œλ‚˜ 2개의 ν”Όμ—°μ‚°μž 쀑 μ–΄λŠ ν•œμͺ½μœΌλ‘œ ν‰κ°€λœλ‹€. λ‹€μŒ 예제λ₯Ό μ‚΄νŽ΄λ³΄μž

despiteallthat.tistory.com

πŸ“Œμš”μ•½

main λ©”μ„œλ“œλŠ” μžλ°” ν”„λ‘œκ·Έλž¨μ˜ μ§„μž…μ (entry point), 즉 μ‹œμž‘μ μ΄λ‹€.

JVM은 μžλ°” ν”„λ‘œκ·Έλž¨ μ‹€ν–‰μ‹œ main λ©”μ„œλ“œλ₯Ό μ°Ύμ•„μ„œ μ‹œμž‘ν•˜λ―€λ‘œ main λ©”μ„œλ“œλŠ” ν•„μˆ˜μ μΈ λ©”μ„œλ“œμ΄λ‹€.

  • public: μ ‘κ·Όμ œμ–΄μžλ‘œ, JVM이 main λ©”μ„œλ“œλ₯Ό μ ‘κ·Όν•  수, 찾을 수 μžˆλ‹€.
  • static: μΈμŠ€ν„΄μŠ€ 생성 없이 ν΄λž˜μŠ€κ°€ λ‘œλ“œλ˜λ©΄ λ°”λ‘œ μ‹€ν–‰λ˜μ–΄μ•Όν•˜κ³  ν”„λ‘œκ·Έλž¨ μ‹€ν–‰μ‹œ main λ©”μ„œλ“œλŠ” λ©”λͺ¨λ¦¬μ— ν• λ‹Ήλ˜μ–΄ μžˆμ–΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— κ°€λΉ„μ§€ μ»¬λ ‰ν„°μ˜ 정리 λŒ€μƒμ΄ μ•„λ‹ˆμ—¬μ•Ό ν•œλ‹€. 
  • void: main λ©”μ„œλ“œκ°€ μ’…λ£Œλ˜μ—ˆλ‹€λŠ” κ²ƒμ€ ν”„λ‘œκ·Έλž¨μ΄ μ’…λ£Œλ˜μ—ˆλ‹€λŠ” κ²ƒμ„ μ˜λ―Έν•˜λ―€λ‘œ λ°˜ν™˜ν•  λ¦¬ν„΄κ°’도 μ—†λ‹€.
  • String[] args: ν”„λ‘œκ·Έλž¨ μ‹€ν–‰μ‹œ main λ©”μ„œλ“œμ— λ„˜κΈ°λŠ” νŒŒλΌλ―Έν„°μ΄λ‹€.

main λ©”μ„œλ“œλž€?

λ¨Όμ € 이 main λ©”μ„œλ“œκ°€ 무엇인지 μ•Œμ•„λ³΄μž.

main λ©”μ„œλ“œλŠ” Java ν”„λ‘œκ·Έλž¨μ˜ μ§„μž…μ (entry point)둜, ν”„λ‘œκ·Έλž¨μ΄ 싀행될 λ•Œ κ°€μž₯ λ¨Όμ € ν˜ΈμΆœλœλ‹€.

그리고 λͺ¨λ“  μžλ°” μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ€ main λ©”μ„œλ“œλ₯Ό ν•„μˆ˜λ‘œ ν¬ν•¨ν•΄μ•Όν•œλ‹€.

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

 

πŸ’‘ μ§„μž…μ (entry point)

μ§„μž…μ μ΄λž€ ν”„λ‘œκ·Έλž¨μ΄ μ‹œμž‘λ˜λŠ” μ‹œμž‘μ μœΌλ‘œ, main λ©”μ„œλ“œκ°€ 이에 ν•΄λ‹Ήν•œλ‹€.

컴퓨터가 ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•  λ•Œ κ°€μž₯ λ¨Όμ € main λ©”μ„œλ“œλ₯Ό μ°Ύμ•„μ„œ κ·Έ μ•ˆμ— μžˆλŠ” μ½”λ“œλ₯Ό μ‹€ν–‰ν•œλ‹€.

즉, ν”„λ‘œκ·Έλž¨μ„ μ‹œμž‘ν•  λ•Œ 컴퓨터가 μ–΄λ””μ„œλΆ€ν„° μ‹€ν–‰ν•΄μ•Όν• μ§€λ₯Ό μ•Œλ €μ£ΌλŠ” 역할을 ν•˜λŠ” 것이닀.

λͺ¨λ“  μžλ°” ν”„λ‘œκ·Έλž¨μ€ main λ©”μ„œλ“œλ₯Ό ν¬ν•¨ν•΄μ•Όν•˜λŠ” μ΄μœ κ°€ 이에 μžˆλ‹€. main λ©”μ„œλ“œκ°€ μ—†μœΌλ©΄ ν”„λ‘œκ·Έλž¨μ΄ μ–΄λ””μ„œ μ‹œμž‘ν•΄μ•Όν• μ§€λ₯Ό λͺ°λΌμ„œ μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.

 

*κ΄€λ‘€μ μœΌλ‘œ ν”„λ‘œκ·Έλž¨μ˜ μ‹œμž‘μ μ„ main으둜 ν•œλ‹€κ³  ν•œλ‹€!

 

main λ©”μ„œλ“œκ°€ μžλ°” ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λ €λ©΄ ν•„μˆ˜μ μœΌλ‘œ μžˆμ–΄μ•Όν•˜κ³ , κ°€μž₯ λ¨Όμ € μ‹€ν–‰λœλ‹€λŠ” 것을 μ•Œμ•„λ³΄μ•˜μœΌλ‹ˆ 이제 ν•˜λ‚˜μ”© λœ―μ–΄λ³΄μž!

public

public은 μ ‘κ·Ό μ œμ–΄μž(access modifier)쀑 ν•˜λ‚˜λ‘œ, μ–΄λ””μ„œλ“  ν•΄λ‹Ή 객체λ₯Ό μ°Έμ‘°ν•  수 μžˆλŠ” μ ‘κ·Ό μ œμ–΄μžμ΄λ‹€.

main λ©”μ„œλ“œλŠ” μ§„μž…μ (entry point)이기 λ•Œλ¬Έμ— JVMμ—μ„œ 이 main λ©”μ„œλ“œλ₯Ό μ–΄λŠκ³³μ—μ„œλ“  μ ‘κ·Όν•˜κΈ° μœ„ν•΄ public μ΄μ—¬μ•Όν•œλ‹€.

 

JVM이 μžλ°” ν”„λ‘œκ·Έλž¨μ„ μ‹œμž‘ν•˜κ³  main λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜λ €λŠ” μ‹œμ μ€ 아직 μ•„λ¬΄λŸ° ν΄λž˜μŠ€λ„ λ‘œλ“œλ˜μ–΄μžˆμ§€ μ•Šμ€ μƒνƒœμ΄λ‹€.

κ°€μž₯ λ¨Όμ € main λ©”μ„œλ“œκ°€ μ–΄λ–€ ν΄λž˜μŠ€μ— μžˆλŠ”μ§€λ₯Ό μ°Ύκ³ , κ·Έ ν΄λž˜μŠ€μ—μ„œ λΆˆλŸ¬μ˜€λŠ” 과정이 ν•„μš”ν•˜λ‹€.

κ·Έλž˜μ„œ 이 main λ©”μ„œλ“œμ— μ ‘κ·Ό μ œμ•½μ΄ 생긴닀면 JVM은 main λ©”μ„œλ“œλ₯Ό μ°Ύμ§€ λͺ»ν•΄μ„œ ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰μ‹œν‚¬ 수 μ—†λŠ” 것이닀.

μ΄λ ‡κ²Œ 되면 μžλ°” ν”„λ‘œκ·Έλž¨ 싀행이 μ•ˆλ˜λ―€λ‘œ, main λ©”μ„œλ“œμ—λŠ” μ•„λ¬΄λŸ° μ œμ•½μ΄ 없도둝 public을 써주어야 ν•œλ‹€.

 

μ ‘κ·Όμ œμ–΄μžλ‘œ public 이 μ•„λ‹ˆλΌ private둜 μ‹€ν–‰ν•˜λ©΄ μ•„λž˜μ™€ 같은 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.  

였λ₯˜: javafx.application.Application ν΄λž˜μŠ€μ—μ„œ κΈ°λ³Έ λ©”μ†Œλ“œκ°€ Main3이(κ°€) μ•„λ‹™λ‹ˆλ‹€. λ‹€μŒ ν˜•μ‹μœΌλ‘œ κΈ°λ³Έ λ©”μ†Œλ“œλ₯Ό μ •μ˜ν•˜μ‹­μ‹œμ˜€.
   public static void main(String[] args)

 

static

static 은 μΈμŠ€ν„΄μŠ€ 생성없이 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆκ²Œν•˜λŠ” ν‚€μ›Œλ“œλ‘œ, 정적 ν•¨μˆ˜μž„μ„ μ˜λ―Έν•œλ‹€.

static으둜 μ„ μ–Έν•œ 속성과 λ©”μ„œλ“œλŠ” μΈμŠ€ν„΄μŠ€μ™€ 관계없이 항상 μΌμ •ν•œ 값을 κ°€μ§€λ―€λ‘œ ꡳ이 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ§€ μ•Šμ•„λ„ μ‚¬μš©ν•  수 μžˆκ²Œλ” λ§Œλ“€μ–΄μ§„ 것이닀.

 

JVM이 main λ©”μ„œλ“œλ₯Ό λ°œκ²¬ν•˜λ©΄ main λ©”μ„œλ“œκ°€ λ“€μ–΄μžˆλŠ” 클래슀λ₯Ό λ‘œλ“œν•œλ‹€.

κ·Έ ν›„ λ³„λ„λ‘œ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” 과정을 κ±°μΉ˜μ§€ μ•Šκ³  ν΄λž˜μŠ€κ°€ λ‘œλ“œλ˜λ©΄ λ°”λ‘œ main λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— static ν‚€μ›Œλ“œλ₯Ό λΆ™μ—¬μ£Όμ–΄μ•Ό ν•œλ‹€.

 

그리고 static으둜 μ„ μ–Έν•œ 속성과 λ©”μ„œλ“œλŠ” ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λŠ” μˆœκ°„ λ©”λͺ¨λ¦¬κ°€ ν• λ‹Ήλ˜κ³ , κ°€λΉ„μ§€ μ»¬λ ‰ν„°μ˜ λ©”λͺ¨λ¦¬ μ •λ¦¬λŒ€μƒμ΄ μ•„λ‹ˆλ‹€.

즉, static으둜 μ„ μ–Έν•œ 속성과 λ©”μ„œλ“œλŠ” λ©”λͺ¨λ¦¬μ— 항상 ν• λ‹Ήλ˜μ–΄ μžˆλ‹€λŠ” 것이닀. 

main λ©”μ„œλ“œλŠ” κ°€λΉ„μ§€ 컬렉터에 μ˜ν•΄ μ •λ¦¬λ˜μ–΄μ„œλŠ” μ•ˆλ˜λŠ” κΈ°λ³Έ ν•¨μˆ˜μ΄λ―€λ‘œ static을 λΆ™μ—¬μ•Όν•œλ‹€.

 

void

void λŠ” λ©”μ„œλ“œμ˜ 리턴 값이 μ—†μŒμ„ μ˜λ―Έν•œλ‹€. μžλ°”λŠ” λ©”μ„œλ“œμ˜ 싀행이 μ’…λ£Œλ˜λ©΄ 리턴 νƒ€μž…μ„ λͺ…μ‹œν•΄μ•Όν•˜λŠ” 언어이기 λ•Œλ¬Έμ— main λ©”μ„œλ“œμ—λ„ λͺ…μ‹œλ˜μ–΄μžˆμ–΄μ•Ό ν•œλ‹€.

main λ©”μ„œλ“œκ°€ μ’…λ£Œλ˜μ—ˆλ‹€λŠ” 것은 ν”„λ‘œκ·Έλž¨μ΄ μ’…λ£Œλ˜μ—ˆλ‹€λŠ” 것을 μ˜λ―Έν•˜λ―€λ‘œ λ°˜ν™˜ν•  리턴값도 μ—†λ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ— voidλ₯Ό λΆ™μ—¬μ€€λ‹€.

 

String[] args

String[] argsλŠ” μ»€λ§¨λ“œ 라인의 argumentλ“€λ‘œ, μ»€λ§¨λ“œ 라인을 톡해 main λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” String νƒ€μž…μ˜ 데이터λ₯Ό 전달할 수 μžˆλ‹€.

*String[]λŠ” String νƒ€μž…μ˜ μ—¬λŸ¬ 값을 μ €μž₯ν•  수 μžˆλŠ” μ €μž₯ꡬ쑰이닀.

JVM이 main λ©”μ„œλ“œμ˜ λ³€μˆ˜λͺ…은 κ°•μ œν•˜μ§€ μ•ŠκΈ°μ— λ³€μˆ˜λͺ…은 μž„μ˜λ‘œ 변경해도 잘 λ™μž‘ν•œλ‹€.

ν•˜μ§€λ§Œ String[]  args ꡬ문 자체λ₯Ό λΉΌλ©΄ μ•ˆλœλ‹€. 일반 λ©”μ„œλ“œλŠ” main λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ ν˜ΈμΆœν•˜κΈ° λ•Œλ¬Έμ— μž…λ ₯값을 main λ©”μ„œλ“œμ—μ„œ μ •ν•  수 μžˆμ§€λ§Œ, main λ©”μ„œλ“œλŠ” ν”„λ‘œκ·Έλž¨ μ‹€ν–‰μ‹œ 처음으둜 μˆ˜ν–‰λ˜κΈ° λ•Œλ¬Έμ— μ™ΈλΆ€λ‘œλΆ€ν„° 값을 받을 수 μžˆμ–΄μ•Όν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

즉, main λ©”μ„œλ“œλŠ” ν”„λ‘œκ·Έλž¨ λ‚΄λΆ€μ—μ„œ 값을 ν˜ΈμΆœν•  수 μ—†κΈ° λ•Œλ¬Έμ— λ¬Έμžμ—΄ 인자λ₯Ό 받을 수 μžˆλ„λ‘ ν•΄μ•Όν•œλ‹€λŠ” 것이닀.

 

ν•˜μ§€λ§Œ IntelliJλ‚˜ Eclipse 같은 IDE둜 Java ν”„λ‘œκ·Έλž¨μ„ κ΅¬ν˜„ν•˜κ³  μ‹€ν–‰ν•˜λŠ” μš”μ¦˜μ—λŠ” main λ©”μ„œλ“œμ— λ¬Έμžμ—΄μ„ 전달할 일이 거의 μ—†λ‹€. μœ„μ— κΈ°μž¬ν–ˆλ“―μ΄ μ»€λ§¨λ“œλΌμΈμ˜ μΈμžκ°’μœΌλ‘œ, Javaκ°€ DOS ν™˜κ²½μ—μ„œ μ‹€ν–‰λ˜λ˜ λ•Œμ— μ‚¬μš©ν•˜λ˜ 것이닀. 

λͺ…λ Ή ν”„λ‘¬ν”„νŠΈ(cmd)λ“±μ˜ 터미널을 ν†΅ν•΄μ„œ μžλ°”λ₯Ό μ‹€ν–‰ν•  λ•Œ μΈμžκ°’μ΄λΌκ³  μƒκ°ν•˜λ©΄ λœλ‹€. 

 

예λ₯Όλ“€μ–΄ μ•„λž˜μ™€ 같은 μžλ°” νŒŒμΌμ„ μ»΄νŒŒμΌν•˜κ³  μ‹€ν–‰μ‹œ μΈμžκ°’μ„ λ„£μ–΄μ„œ 확인해보겠닀.

package project01;

import java.util.Arrays;

public class Solution01 {
	public static void main(String[] args) {
		System.out.println(Arrays.toString(args));
	}
}

 

μœˆλ„μš°μ˜ 경우 λͺ…λ Ή ν”„λ‘¬ν”„νŠΈ(cmd)μ—μ„œ 싀행해보면 μ•„λž˜μ™€ 같이 μΈμžκ°’μ„ 잘 λ°›μ•„μ„œ 좜λ ₯ν•΄μ€€λ‹€λŠ” 것을 μ•Œ 수 μžˆλ‹€.

ν•΄λ‹Ή μžλ°” 파일이 μžˆλŠ” λ””λ ‰ν† λ¦¬μ—μ„œ λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•΄μ„œ μˆ˜ν–‰ν•œλ‹€.

  • java Solution01.java : java 파일 컴파일
  • java project01.Solution01 test string HelloWorld : μ»΄νŒŒμΌν•œ μžλ°” νŒŒμΌμ„ μ‹€ν–‰
    • projext01.Solution01: νŒ¨ν‚€μ§€λͺ….클래슀λͺ…
    • test string HelloWorld κ°€ main λ©”μ„œλ“œμ˜ μΈμžκ°’μœΌλ‘œ λ“€μ–΄κ°€λŠ” String[] args에 ν•΄λ‹Ήν•˜λŠ” 뢀뢄이닀.

*쀑간에 cd .. λ₯Ό ν•˜λŠ” μ΄μœ λŠ” μƒμœ„ ν΄λ”λ‘œ μ΄λ™ν•˜κΈ° μœ„ν•΄μ„œ!

λ¬Όλ‘  IDE μ—μ„œλ„ 섀정을 ν•˜λ©΄ main λ©”μ„œλ“œμ— String λ°°μ—΄ 인자λ₯Ό 전달할 수 μžˆλ‹€κ³  ν•œλ‹€.

 

μ°Έκ³  ν¬μŠ€νŒ…

 

Java λ©”μΈλ©”μ†Œλ“œ public static void main(String[] args) μ΄ν•΄ν•˜κΈ°

public static void main(String[] args) μžλ°”μ˜ λͺ¨λ“  ν”„λ‘œκ·Έλž¨μ€ public static void main (String[] args)ν•¨μˆ˜λ‘œ μ‹œμž‘ν•œλ‹€. μ΄λ ‡κ²Œ μ‹œμž‘ν•˜λŠ” 것은 μžλ°”μ˜ κ·œμΉ™μ΄λ‹€. λ‹€μˆ˜μ˜ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ mainν•¨μˆ˜κ°€ μ—”νŠΈλ¦¬ 포

devparker.tistory.com

 

[Java] main λ©”μ†Œλ“œ λ½€κ°œκΈ°

μžλ°” 책을 νŽΌμ³€λ‹€. Hello World μ˜ˆμ œκ°€ λ‚˜μ˜€λ©΄μ„œ main λ©”μ†Œλ“œλŠ” μ΄λ ‡κ²Œ μƒκ²¨λ¨Ήμ€κ±°λ‹ˆ 일단 λ„˜μ–΄κ°€λž€λ‹€. λ‚΄κ°€ 펼친 책은 μžλ°”λ₯Ό 처음 λ°°μš°λŠ” μ‚¬λžŒμ„ μœ„ν•΄ μ“°μ—¬μ‘Œμ§€λ§Œ, λ‚˜λŠ” 처음 λ°°μš°λŠ” μ‚¬λžŒμ΄ μ•„λ‹ˆλ―€

velog.io

 

[Java] public static void main(String[] args)λŠ” 무슨 λœ»μΈκ°€μš”?

μš”μ•½ mainν•¨μˆ˜λŠ” μžλ°” ν”„λ‘œκ·Έλž¨μ˜ μ‹œμž‘μ μ΄λ‹€. μžλ°”κ°€μƒλ¨Έμ‹ (JVM)은 mainμ΄λΌλŠ” 이름을 κ°€μ§„ λ©”μ„œλ“œλ₯Ό μ°Ύμ•„ ν”„λ‘œκ·Έλž¨μ„ μ‹œμž‘ν•œλ‹€. - public : JVM이 mainν•¨μˆ˜λ₯Ό 찾을 수 μžˆλ„λ‘ ν•œλ‹€. - static : JVM이 main함

atomicliquors.tistory.com

 

[κΈ°μˆ λ©΄μ ‘] java λ©΄μ ‘ 질문 리슀트 λ‹΅λ³€ 포함

μ»΄νŒŒμΌκ³Όμ •1-1. compiler vs interpreter μ»΄νŒŒμΌμ΄λž€ κ³ κΈ‰μ–Έμ–΄λ‘œ μž‘μ„±λœ .javaνŒŒμΌμ„ 기계어인 byte code 즉, .class파일둜 λ³€ν™˜ν•˜λŠ” 과정을 λ§ν•©λ‹ˆλ‹€. 컴파일 κ³Όμ • 첫번째둜 ν”„λ‘œκ·Έλž˜λ¨Έκ°€ javaμ–Έμ–΄λ‘œ μ†ŒμŠ€μ½”

velog.io

 

✏️ μ½”λ”©ν…ŒμŠ€νŠΈλ₯Ό ν’€λ©΄μ„œ int[] λ₯Ό List둜 λ³€ν™˜ν•˜λ‹€κ°€ λ§ˆμ£Όν•œ λ¬Έμ œμ™€ μ•Œκ²Œλœ 문법에 λŒ€ν•œ ν¬μŠ€νŒ…

 

int[ ] to List<Integer>

int 배열을 List둜 λ³€ν™˜ν•˜λŠ” 방법, 즉 int 배열에 λ‹΄κΈ΄ μš”μ†Œλ₯Ό κ·ΈλŒ€λ‘œ List<Integer> (=ArrayList<Integer>)νƒ€μž…μœΌλ‘œ λ³€ν™˜ν•˜λŠ” 방법을 μ•„λž˜μ™€ 같이 μ‹œλ„ν–ˆμ—ˆλ‹€.

 

❌ Fail : Arrays.asList()둜 λ³€ν™˜

Arrays.asList()에 int λ°°μ—΄(int[])을 λ§€κ°œλ³€μˆ˜λ‘œ κ·ΈλŒ€λ‘œ λ‹΄μœΌλ©΄ List<int[]>ν˜•μœΌλ‘œ λ³€ν™˜λœλ‹€.

// int λ°°μ—΄
int[] arr = {1,2,3,4};

// 리슀트둜 λ³€ν™˜
List<int[]> list = Arrays.asList(arr);

// κ²°κ³Ό
System.out.println(list.size());                    // 1
System.out.println(list.get(0));                    // [I@36baf30c
System.out.println(Arrays.toString(list.get(0)));   // [1, 2, 3, 4]

int 배열인 arr을 asList둜 λ³€ν™˜ν–ˆμ„λ•Œ κΈ°λŒ€ν•œ 건 arr의 μš”μ†Œ(1,2,3,4)λ₯Ό κ°€μ§„ List<Integer> νƒ€μž…μ΄μ§€λ§Œ, List<int[]>둜 λ°˜ν™˜λœλ‹€.

λ‚΄κ°€ μ›ν•˜λŠ” List<Integer> νƒ€μž…μ΄ μ•„λ‹ˆλ‹€!

 

κ²°λ‘ λΆ€ν„° λ§ν•˜μžλ©΄,

Arrays.asList()λŠ” primitive νƒ€μž…μ„ Wrapper 클래슀둜 ν˜•λ³€ν™˜ν•΄μ£Όμ§€ μ•ŠλŠ”λ‹€.

즉, int νƒ€μž…μ„ Integer둜 ν˜•λ³€ν™˜ν•΄μ£Όμ§€ μ•ŠκΈ°λ•Œλ¬Έμ—,
primitive νƒ€μž…μ˜ 배열은 Arrays.asList()λ₯Ό μ‚¬μš©ν•΄μ„œ List둜 λ³€ν™˜ν•  수 μ—†λ‹€.

 

λ”°λΌμ„œ int νƒ€μž…μ˜ 배열은 λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ λ°°μ—΄μ—μ„œ List둜 λ³€ν™˜ν•΄μ•Όν•œλ‹€.

1) λ°˜λ³΅λ¬Έμ„ μ‚¬μš©ν•˜κ±°λ‚˜ 2) Stream을 μ‚¬μš©ν•΄μ„œ λ³€ν™˜ν•˜λŠ” 방식이 μžˆλ‹€.

 

βœ… Success : 반볡문 or Stream μ‚¬μš©ν•΄μ„œ λ³€ν™˜

1. 반볡문

// int λ°°μ—΄
int[] arr = {1,2,3,4};

// 리슀트둜 λ³€ν™˜
List<Integer> list = new ArrayList<>();
for (int el: arr) {
    list.add(el);
}

// κ²°κ³Ό
System.out.println(list.size());    // 4
System.out.println(list);           // [1, 2, 3, 4]

 

μœ„μ²˜λŸΌ λ°˜λ³΅λ¬Έμ„ 톡해 int 배열을 μˆœνšŒν•˜λ©΄μ„œ list에 값을 ν•˜λ‚˜μ”© μΆ”κ°€ν•΄μ£Όλ©΄ λœλ‹€.

κ²°κ³Όλ₯Ό 확인해보면 List에 Integer μš”μ†Œ 4κ°œκ°€ κ·ΈλŒ€λ‘œ λ“€μ–΄κ°€ μžˆλŠ”κ²ƒμ„ 확인할 수 μžˆλ‹€.

 

2. Stream 

Stream은 λžŒλ‹€μ™€ ν•¨κ»˜ μ‚¬μš©λ˜μ–΄ κ°„κ²°ν•˜κ²Œ ν‘œν˜„ κ°€λŠ₯ν•œ κΈ°λŠ₯으둜, Java 8λΆ€ν„° μ§€μ›λœλ‹€.

// int λ°°μ—΄
int[] arr = {1,2,3,4};

// 리슀트둜 λ³€ν™˜
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());

// κ²°κ³Ό
System.out.println(list.size());    // 4
System.out.println(list);           // [1, 2, 3, 4]
  • Arrays.stream(arr) : int[] → IntStream
  • boxed() : IntStream → Stream<Integer>
  • collect(Collectors.toList()) : Stream<Integer> → ArrayList<Integer>
    • Stream의 데이터λ₯Ό λ³€ν˜• λ“±μ˜ 처리λ₯Ό ν•˜κ³  μ›ν•˜λŠ” μžλ£Œν˜•μœΌλ‘œ λ³€ν™˜
    • collect: 슀트림의 μ΅œμ’…μ—°μ‚°μœΌλ‘œ, λ§€κ°œλ³€μˆ˜λ‘œλŠ” Collectorλ₯Ό ν•„μš”λ‘œ 함
    • Collectors.toList(): Collectorsλ₯Ό μ΄μš©ν•˜μ—¬ 슀트림의 μš”μ†Œλ“€μ„ List 객체둜 λ³€ν™˜
      *Collectors: 미리 μž‘μ„±λœ λ‹€μ–‘ν•œ Collectorλ₯Ό λ°˜ν™˜ν•˜λŠ” static λ©”μ„œλ“œλ₯Ό κ°€μ§€κ³  μžˆλ‹€.

 

μ΄λ ‡κ²Œ int[]λ₯Ό List<Integer>둜 λ³€ν™˜ν•˜λŠ”λ° μ„±κ³΅ν–ˆλŠ”λ°,

λ‹€μŒμ—λŠ” 배열을 리슀트둜 λ³€ν™˜ν•˜λŠ” 방법을 더 μ•Œμ•„λ³΄κ³ ,

Arrays.asList()와 new ArrayList<>()둜 μƒμ„±λœ List의 차이점도 ν¬μŠ€νŒ… ν•΄μ•Όκ² λ‹€.

 

 

μ°Έκ³  ν¬μŠ€νŒ…

μžλ°” ν”„λ‘œκ·Έλž˜λ¨Έκ°€ 자주 μ‹€μˆ˜ ν•˜λŠ” 10κ°€μ§€ - 1

[JAVA] Forκ³Ό Stream은 μ–΄λ–€ μ°¨μ΄κ°€ μžˆλŠ”κ±ΈκΉŒ?

+ Recent posts