πŸ“– Java/πŸ’Š Java κ°•μ˜

Java 기본편 κ°•μ˜_κΈ°λ³Έν˜•κ³Ό μ°Έμ‘°ν˜•

carrot0911 2024. 11. 26. 01:26

κΈ°λ³Έν˜•κ³Ό μ°Έμ‘°ν˜•

 

κΈ°λ³Έν˜• vs μ°Έμ‘°ν˜• 1 - μ‹œμž‘

μžλ°”μ—μ„œ μ°Έμ‘°ν˜•μ„ μ œλŒ€λ‘œ μ΄ν•΄ν•˜λŠ” 것은 정말 μ€‘μš”ν•˜λ‹€.

λ³€μˆ˜μ˜ 데이터 νƒ€μž…μ„ κ°€μž₯ 크게 보면 κΈ°λ³Έν˜•κ³Ό μ°Έμ‘°ν˜•μœΌλ‘œ λΆ„λ₯˜ν•  수 μžˆλ‹€. μ‚¬μš©ν•˜λŠ” 값을 λ³€μˆ˜μ— 직접 넣을 수 μžˆλŠ” κΈ°λ³Έν˜•, 객체가 μ €μž₯된 λ©”λͺ¨λ¦¬μ˜ μœ„μΉ˜λ₯Ό κ°€λ₯΄ν‚€λŠ” 참쑰값을 넣을 수 μžˆλŠ” μ°Έμ‘°ν˜•μœΌλ‘œ λΆ„λ₯˜ν•  수 μžˆλ‹€.

  • κΈ°λ³Έν˜•(Primitive Type) : int, long, double, boolean처럼 λ³€μˆ˜μ— μ‚¬μš©ν•  값을 직접 넣을 수 μžˆλŠ” 데이터 νƒ€μž…μ„ κΈ°λ³Έν˜•μ΄λΌ ν•œλ‹€.
  • μ°Έμ‘°ν˜•(Reference Type) : 데이터에 μ ‘κ·Όν•˜κΈ° μœ„ν•œ μ°Έμ‘°(μ£Όμ†Œ)λ₯Ό μ €μž₯ν•˜λŠ” 데이터 νƒ€μž…μ„ μ°Έμ‘°ν˜•μ΄λΌ ν•œλ‹€. μ°Έμ‘°ν˜•μ€ 객체 λ˜λŠ” 배열에 μ‚¬μš©λœλ‹€.

κΈ°λ³Έν˜• λ³€μˆ˜μ—λŠ” 직접 μ‚¬μš©ν•  수 μžˆλŠ” 값이 λ“€μ–΄μžˆμ§€λ§Œ μ°Έμ‘°ν˜• λ³€μˆ˜μ—λŠ” μœ„μΉ˜(μ°Έμ‘°κ°’)κ°€ λ“€μ–΄κ°€ μžˆλ‹€. μ°Έμ‘°ν˜• λ³€μˆ˜λ₯Ό ν†΅ν•΄μ„œ λ­”κ°€ ν•˜λ €λ©΄ κ²°κ΅­ 참쑰값을 톡해 ν•΄λ‹Ή μœ„μΉ˜λ‘œ 이동해야 ν•œλ‹€.

κΈ°λ³Έν˜• vs μ°Έμ‘°ν˜• - κΈ°λ³Έ

  • κΈ°λ³Έν˜•μ€ 숫자 10, 20κ³Ό 같이 μ‹€μ œ μ‚¬μš©ν•˜λŠ” 값을 λ³€μˆ˜μ— 담을 수 μžˆλ‹€. κ·Έλž˜μ„œ ν•΄λ‹Ή 값을 λ°”λ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.
  • μ°Έμ‘°ν˜•μ€ μ‹€μ œ μ‚¬μš©ν•˜λŠ” 값을 λ³€μˆ˜μ— λ‹΄λŠ” 것이 μ•„λ‹ˆλ‹€. 이름 κ·ΈλŒ€λ‘œ μ‹€μ œ 객체의 μœ„μΉ˜(μ°Έμ‘°, μ£Όμ†Œ)λ₯Ό μ €μž₯ν•œλ‹€. μ°Έμ‘°ν˜•μ—λŠ” 객체와 배열이 μžˆλ‹€.
    • κ°μ²΄λŠ” .(dot)을 톡해 λ©”λͺ¨λ¦¬ 상에 μƒμ„±λœ 객체λ₯Ό μ°Ύμ•„κ°€μ•Ό μ‚¬μš©ν•  수 μžˆλ‹€.
    • 배열은 [ ]λ₯Ό ν†΅ν•΄μ„œ λ©”λͺ¨λ¦¬ 상에 μƒμ„±λœ 배열을 μ°Ύμ•„κ°€μ•Ό μ‚¬μš©ν•  수 μžˆλ‹€.

κΈ°λ³Έν˜•μ€ 연산이 κ°€λŠ₯ν•˜μ§€λ§Œ μ°Έμ‘°ν˜•μ€ 연산이 λΆˆκ°€λŠ₯ν•˜λ‹€.
κΈ°λ³Έν˜•μ€ λ³€μˆ˜μ— μ‹€μ œ μ‚¬μš©ν•˜λŠ” 값이 λ‹΄κ²¨μžˆλ‹€. +, -와 같은 연산이 κ°€λŠ₯ν•˜λ‹€.
μ°Έμ‘°ν˜•μ€ λ³€μˆ˜μ— 객체의 μœ„μΉ˜μΈ 참쑰값이 λ“€μ–΄ μžˆλ‹€. 참쑰값은 계산에 μ‚¬μš©ν•  수 μ—†λ‹€. λ”°λΌμ„œ 였λ₯˜κ°€ λ°œμƒν•œλ‹€.
λ¬Όλ‘  .을 톡해 객체의 κΈ°λ³Έν˜• 멀버 λ³€μˆ˜μ— μ ‘κ·Όν•œ κ²½μš°μ—λŠ” 연산을 ν•  수 μžˆλ‹€.

βœ”οΈ μ‰½κ²Œ μ΄ν•΄ν•˜λŠ” 팁

κΈ°λ³Έν˜•μ„ μ œμ™Έν•œ λ‚˜λ¨Έμ§€λŠ” λͺ¨λ‘ μ°Έμ‘°ν˜•μ΄λ‹€.
κΈ°λ³Έν˜•μ€ μ†Œλ¬Έμžλ‘œ μ‹œμž‘ν•œλ‹€. int, long, double, boolean λͺ¨λ‘ μ†Œλ¬Έμžλ‘œ μ‹œμž‘ν•œλ‹€.
κΈ°λ³Έν˜•μ€ Javaκ°€ 기본으둜 μ œκ³΅ν•˜λŠ” 데이터 νƒ€μž…μ΄λ‹€. μ΄λŸ¬ν•œ κΈ°λ³Έν˜•μ€ κ°œλ°œμžκ°€ μƒˆλ‘œ μ •μ˜ν•  수 μ—†λ‹€.
κ°œλ°œμžλŠ” μ°Έμ‘°ν˜•μΈ 클래슀만 직접 μ •μ˜ν•  수 μžˆλ‹€.


ν΄λž˜μŠ€λŠ” λŒ€λ¬Έμžλ‘œ μ‹œμž‘ν•œλ‹€. Student
ν΄λž˜μŠ€λŠ” λͺ¨λ‘ μ°Έμ‘°ν˜•μ΄λ‹€.
βœ”οΈ μ°Έκ³  - String

Javaμ—μ„œ String은 νŠΉλ³„ν•˜λ‹€. String은 사싀은 ν΄λž˜μŠ€μ΄λ‹€. λ”°λΌμ„œ μ°Έμ‘°ν˜•μ΄λ‹€.
그런데 κΈ°λ³Έν˜•μ²˜λŸΌ 문자 값을 λ°”λ‘œ λŒ€μž…ν•  수 μžˆλ‹€.
λ¬ΈμžλŠ” 맀우 자주 닀루기 λ•Œλ¬Έμ— Javaμ—μ„œ νŠΉλ³„ν•˜κ²Œ 편의 κΈ°λŠ₯을 μ œκ³΅ν•œλ‹€.

 

κΈ°λ³Έν˜• vs μ°Έμ‘°ν˜• 2 - λ³€μˆ˜ λŒ€μž…

λŒ€μ›μΉ™ : JavaλŠ” 항상 λ³€μˆ˜μ˜ 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.

Javaμ—μ„œ λ³€μˆ˜μ— 값을 λŒ€μž…ν•˜λŠ” 것은 λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•˜λŠ” 것이닀.
κΈ°λ³Έν˜•, μ°Έμ‘°ν˜• λͺ¨λ‘ 항상 λ³€μˆ˜μ— μžˆλŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.
κΈ°λ³Έν˜•μ΄λ©΄ λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” μ‹€μ œ μ‚¬μš©ν•˜λŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•˜κ³ , μ°Έμ‘°ν˜•μ΄λ©΄ λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” 참쑰값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.

κΈ°λ³Έν˜•μ€ λ³€μˆ˜μ— 값을 λŒ€μž…ν•˜λ”λΌλ„ μ‹€μ œ μ‚¬μš©ν•˜λŠ” 값이 λ³€μˆ˜μ— λ°”λ‘œ λ“€μ–΄ 있기 λ•Œλ¬Έμ— ν•΄λ‹Ή κ°’λ§Œ λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€κ³  μƒκ°ν•˜λ©΄ μ‰½κ²Œ 이해할 수 μžˆλ‹€. 
그런데 μ°Έμ‘°ν˜•μ˜ 경우 μ‹€μ œ μ‚¬μš©ν•˜λŠ” 객체가 μ•„λ‹ˆλΌ 객체의 μœ„μΉ˜λ₯Ό κ°€λ₯΄ν‚€λŠ” μ°Έμ‘°κ°’λ§Œ λ³΅μ‚¬λœλ‹€. μ‰½κ²Œ μ΄μ•ΌκΈ°ν•΄μ„œ μ‹€μ œ 건물이 볡사가 λ˜λŠ” 것이 μ•„λ‹ˆλΌ 건물의 μœ„μΉ˜μΈ μ£Όμ†Œλ§Œ λ³΅μ‚¬λ˜λŠ” 것이닀.
λ”°λΌμ„œ 같은 건물을 μ°Ύμ•„κ°ˆ 수 μžˆλŠ” 방법이 ν•˜λ‚˜ λŠ˜μ–΄λ‚  뿐이닀.

κΈ°λ³Έν˜•κ³Ό λ³€μˆ˜ λŒ€μž…

VarChange1

package ref;

public class VarChange1 {
    public static void main(String[] args) {
        int a = 10;
        int b = a;

        System.out.println("a = " + a);
        System.out.println("b = " + b);

        // a λ³€κ²½
        a = 20;
        System.out.println("λ³€κ²½ a = 20");
        System.out.println("a = " + a);
        System.out.println("b = " + b);

        // b λ³€κ²½
        b = 30;
        System.out.println("λ³€κ²½ b = 30");
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }
}

μ—¬κΈ°μ„œ 핡심은 int b = a라고 ν–ˆμ„ λ•Œ λ³€μˆ˜μ— λ“€μ–΄μžˆλŠ” 값을 λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•œλ‹€λŠ” 점이닀. λ”°λΌμ„œ a = 20, b = 30이라고 ν–ˆμ„ λ•Œ 각각 본인의 κ°’λ§Œ λ³€κ²½λ˜λŠ” 것을 확인할 수 μžˆλ‹€.

μ°Έμ‘°ν˜•κ³Ό λ³€μˆ˜ λŒ€μž…

Data

package ref;

public class Data {
    int value;
}

VarChange2

package ref;

public class VarChange2 {
    public static void main(String[] args) {
        Data dataA = new Data();
        dataA.value = 10;
        Data dataB = dataA;

        System.out.println("dataA μ°Έμ‘°κ°’=" + dataA);  // ref.Data@41629346
        System.out.println("dataB μ°Έμ‘°κ°’=" + dataB);  // ref.Data@41629346
        System.out.println("dataA.value = " + dataA.value);  // 10
        System.out.println("dataB.value = " + dataB.value);  // 10

        //dataA λ³€κ²½
        dataA.value = 20;
        System.out.println("λ³€κ²½ dataA.value = 20");
        System.out.println("dataA.value = " + dataA.value);  // 20
        System.out.println("dataB.value = " + dataB.value);  // 20

        //dataB λ³€κ²½
        dataB.value = 30;
        System.out.println("λ³€κ²½ dataB.value = 30");
        System.out.println("dataA.value = " + dataA.value);  // 30
        System.out.println("dataB.value = " + dataB.value);  // 30
    }
}

λ³€μˆ˜μ˜ λŒ€μž…μ€ λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€. λ³€μˆ˜ dataAμ—λŠ” μ°Έμ‘°κ°’ x001이 λ“€μ–΄ μžˆλ‹€.
λ³€μˆ˜ dataA에 λ“€μ–΄μžˆλŠ” μ°Έμ‘°κ°’ x001을 λ³΅μ‚¬ν•΄μ„œ λ³€μˆ˜ dataB에 λŒ€μž…ν•œλ‹€.
참고둜 λ³€μˆ˜ dataAκ°€ κ°€λ₯΄ν‚€λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό λ³΅μ‚¬ν•˜λŠ” 것이 μ•„λ‹ˆλ‹€! λ³€μˆ˜μ— λ“€μ–΄μžˆλŠ” μ°Έμ‘°κ°’λ§Œ λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•œλ‹€.

Data dataB = dataA라고 ν–ˆμ„ λ•Œ λ³€μˆ˜μ— λ“€μ–΄κ°€λŠ” 값을 λ³΅μ‚¬ν•΄μ„œ μ‚¬μš©ν•œλ‹€λŠ” 점이닀. 그런데 κ·Έ 값이 참쑰값이닀.
λ”°λΌμ„œ dataA와 dataBλŠ” 같은 참쑰값을 κ°€μ§€κ²Œ 되고, 두 λ³€μˆ˜λŠ” 같은 객체 μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•˜κ²Œ λœλ‹€.

 

κΈ°λ³Έν˜• vs μ°Έμ‘°ν˜• 3 - λ©”μ„œλ“œ 호좜

λŒ€μ›μΉ™ : μžλ°”λŠ” 항상 λ³€μˆ˜μ˜ 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.

Javaμ—μ„œ λ³€μˆ˜μ— 값을 λŒ€μž…ν•˜λŠ” 것은 λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•˜λŠ” 것이닀.
κΈ°λ³Έν˜•, μ°Έμ‘°ν˜• λͺ¨λ‘ ν•­μƒ λ³€μˆ˜μ— μžˆλŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.
κΈ°λ³Έν˜•μ΄λ©΄ λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” μ‹€μ œ μ‚¬μš©ν•˜λŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•˜κ³ , μ°Έμ‘°ν˜•이면 λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” 참쑰값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.

λ©”μ„œλ“œ ν˜ΈμΆœλ„ λ§ˆμ°¬κ°€μ§€μ΄λ‹€. λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ μ‚¬μš©ν•˜λŠ” λ§€κ°œλ³€μˆ˜(νŒŒλΌλ―Έν„°)도 κ²°κ΅­ λ³€μˆ˜μΌ 뿐이닀.
λ”°λΌμ„œ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ λ§€κ°œλ³€μˆ˜μ— 값을 μ „λ‹¬ν•˜λŠ” 것도 μ•žμ„œ μ„€λͺ…ν•œ λ‚΄μš©κ³Ό 같이 값을 λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•œλ‹€.

κΈ°λ³Έν˜•κ³Ό λ©”μ„œλ“œ 호좜

package ref;

public class MethodChange1 {
    public static void main(String[] args) {
        int a = 10;
        System.out.println("λ©”μ„œλ“œ 호좜 μ „: a = " + a);  // 10
        changePrimitive(a);
        System.out.println("λ©”μ„œλ“œ 호좜 ν›„: a = " + a);  // 10
    }

    static void changePrimitive(int x) {
        x = 20;
    }
}

μ°Έμ‘°ν˜•κ³Ό λ©”μ„œλ“œ 호좜

package ref;

public class MethodChage2 {
    public static void main(String[] args) {
        Data dataA = new Data();
        dataA.value = 10;
        System.out.println("λ©”μ„œλ“œ 호좜 μ „: dataA.value = " + dataA.value);  // 10
        changeReference(dataA);
        System.out.println("λ©”μ„œλ“œ 호좜 ν›„: dataA.value = " + dataA.value);  // 20
    }

    static void changeReference(Data dataX) {
        dataX.value = 20;
    }
}

κΈ°λ³Έν˜•κ³Ό μ°Έμ‘°ν˜•μ˜ λ©”μ„œλ“œ 호좜
Javaμ—μ„œ λ©”μ„œλ“œμ˜ λ§€κ°œλ³€μˆ˜(νŒŒλΌλ―Έν„°)λŠ” 항상 값에 μ˜ν•΄ μ „λ‹¬λœλ‹€.
κ·ΈλŸ¬λ‚˜ 이 값이 μ‹€μ œ 값이냐, μ°Έμ‘°(λ©”λͺ¨λ¦¬ μ£Όμ†Œ) 값이냐에 따라 λ™μž‘μ΄ 달라진닀.

  • κΈ°λ³Έν˜• : λ©”μ„œλ“œλ‘œ κΈ°λ³Έν˜• 데이터λ₯Ό μ „λ‹¬ν•˜λ©΄, ν•΄λ‹Ή 값이 λ³΅μ‚¬λ˜μ–΄ μ „λ‹¬λœλ‹€. λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ λ§€κ°œλ³€μˆ˜(νŒŒλΌλ―Έν„°)의 값을 변경해도, 호좜자의 λ³€μˆ˜ κ°’μ—λŠ” 영ν–₯이 μ—†λ‹€.
  • μ°Έμ‘°ν˜• : λ©”μ„œλ“œλ‘œ μ°Έμ‘°ν˜• 데이터λ₯Ό μ „λ‹¬ν•˜λ©΄, 참쑰값이 λ³΅μ‚¬λ˜μ–΄ μ „λ‹¬λœλ‹€. λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ λ§€κ°œλ³€μˆ˜(νŒŒλΌλ―Έν„°)둜 μ „λ‹¬λœ 객체의 멀버 λ³€μˆ˜λ₯Ό λ³€κ²½ν•˜λ©΄, 호좜자의 객체도 λ³€κ²½λœλ‹€.

 

μ°Έμ‘°ν˜•κ³Ό λ©”μ„œλ“œ 호좜 - ν™œμš©

ClassStart3

package class1;

public class ClassStart3 {
    public static void main(String[] args) {
        Student student1 = new Student();
        student1.name = "학생1";
        student1.age = 15;
        student1.grade = 90;

        Student student2 = new Student();
        student2.name = "학생2";
        student2.age = 16;
        student2.grade = 80;

        System.out.println("이름: " + student1.name + " λ‚˜μ΄: " + student1.age + " 성적: " + student1.grade);
        System.out.println("이름: " + student2.name + " λ‚˜μ΄: " + student2.age + " 성적: " + student2.grade);
    }
}

쀑볡을 λ©”μ„œλ“œλ₯Ό ν†΅ν•΄μ„œ μ†μ‰½κ²Œ μ œκ±°ν•  수 μžˆλ‹€.

λ©”μ„œλ“œμ— 객체 전달

Student

package ref;

public class Student {
    String name;
    int age;
    int grade;
}

Method1

package ref;

public class Method1 {
    public static void main(String[] args) {
        Student student1 = new Student();
        initStudent(student1, "학생1", 15, 90);

        Student student2= new Student();
        initStudent(student2, "학생2", 16, 80);

        printStudent(student1);
        printStudent(student2);
    }

    static void initStudent(Student student, String name, int age, int grade) {
        student.name = name;
        student.age = age;
        student.grade = grade;
    }

    static void printStudent(Student student) {
        System.out.println("이름: " + student.name + " λ‚˜μ΄: " + student.age + " 성적: " + student.grade);
    }
}

μ°Έμ‘°ν˜•μ€ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ 참쑰값을 μ „λ‹¬ν•œλ‹€.
λ”°λΌμ„œ λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ μ „λ‹¬λœ 참쑰값을 톡해 객체의 값을 λ³€κ²½ν•˜κ±°λ‚˜, 값을 μ½μ–΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

  • initStudent(Student student, ...) : μ „λ‹¬ν•œ 학생 객체의 ν•„λ“œμ— 값을 μ„€μ •ν•œλ‹€.
  • printStudent(Student student) : μ „λ‹¬ν•œ 학생 객체의 ν•„λ“œ 값을 μ½μ–΄μ„œ 좜λ ₯ν•œλ‹€.

 

βœ”οΈ 주의!

package ref;

import class1.Student;

public class Method1 {
    ...
}​

import class1.Student; 이 μ„ μ–Έλ˜μ–΄ 있으면 μ•ˆλœλ‹€.
μ΄λ ‡κ²Œ 되면 class1 νŒ¨ν‚€μ§€μ—μ„œ μ„ μ–Έν•œ Studentλ₯Ό μ‚¬μš©ν•˜κ²Œ λœλ‹€. 이 경우 μ ‘κ·Ό μ œμ–΄μž λ•Œλ¬Έμ— 컴파일 였λ₯˜κ°€ λ°œμƒν•œλ‹€.
λ§Œμ•½ μ„ μ–Έλ˜μ–΄ μžˆλ‹€λ©΄ μ‚­μ œν•˜μž. μ‚­μ œν•˜λ©΄ 같은 νŒ¨ν‚€μ§€μ— μžˆλŠ” ref.Studentλ₯Ό μ‚¬μš©ν•œλ‹€.

 

Method2

package ref;

public class Method2 {
    public static void main(String[] args) {
        Student student1 = createStudent("학생1", 15, 90);
        Student student2 = createStudent("학생2", 16, 80);

        printStudent(student1);
        printStudent(student2);
    }

    static Student createStudent(String name, int age, int grade) {
        Student student = new Student();
        student.name = name;
        student.age = age;
        student.grade = grade;
        return student;
    }

    static void printStudent(Student student) {
        System.out.println("이름: " + student.name + " λ‚˜μ΄: " + student.age + " 성적: " + student.grade);
    }
}

createStudent( )λΌλŠ” λ©”μ„œλ“œλ₯Ό λ§Œλ“€κ³  객체λ₯Ό μƒμ„±ν•˜λŠ” 뢀뢄도 이 λ©”μ„œλ“œ μ•ˆμ— ν•¨κ»˜ ν¬ν•¨ν–ˆλ‹€. 이제 이 λ©”μ„œλ“œ ν•˜λ‚˜λ‘œ 객체의 생성과 μ΄ˆκΈ°κ°’ 섀정을 λͺ¨λ‘ μ²˜λ¦¬ν•œλ‹€.
그런데 λ©”μ„œλ“œ μ•ˆμ—μ„œ 객체λ₯Ό μƒμ„±ν–ˆκΈ° λ•Œλ¬Έμ— λ§Œλ“€μ–΄μ§„ 객체λ₯Ό λ©”μ„œλ“œ λ°–μ—μ„œ μ‚¬μš©ν•  수 μžˆλ„λ‘ λŒλ €μ£Όμ–΄μ•Ό ν•œλ‹€. κ·Έλž˜μ•Ό λ©”μ„œλ“œ λ°–μ—μ„œ 이 객체λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.
λ©”μ„œλ“œλŠ” 호좜 κ²°κ³Όλ₯Ό λ°˜ν™˜(return)을 ν•  수 μžˆλ‹€. λ©”μ„œλ“œμ˜ λ°˜ν™˜ κΈ°λŠ₯을 μ‚¬μš©ν•΄μ„œ λ§Œλ“€μ–΄μ§„ 객체의 참쑰값을 λ©”μ„œλ“œ λ°–μœΌλ‘œ λ°˜ν™˜ν•˜λ©΄ λœλ‹€.

 

λ³€μˆ˜μ™€ μ΄ˆκΈ°ν™”

λ³€μˆ˜μ˜ μ’…λ₯˜

  • 멀버 λ³€μˆ˜(ν•„λ“œ) : ν΄λž˜μŠ€μ— μ„ μ–Έ
  • μ§€μ—­ λ³€μˆ˜ : λ©”μ„œλ“œμ— μ„ μ–Έ, λ§€κ°œλ³€μˆ˜λ„ μ§€μ—­ λ³€μˆ˜μ˜ ν•œ μ’…λ₯˜μ΄λ‹€.

멀버 λ³€μˆ˜, ν•„λ“œ μ˜ˆμ‹œ

public class Student {
    String name;
    int age;
    int grade;
}

μ§€μ—­ λ³€μˆ˜ μ˜ˆμ‹œ

public class ClassStart3 {
    public static void main(String[] args) {
        Student student1;
        student1 = new Student();
        Student student2 = new Student();
    }
}

 

package ref;

public class MethodChange1 {
    public static void main(String[] args) {
        int a = 10;
        System.out.println("λ©”μ„œλ“œ 호좜 μ „: a = " + a);  // 10
        changePrimitive(a);
        System.out.println("λ©”μ„œλ“œ 호좜 ν›„: a = " + a);  // 10
    }

    static void changePrimitive(int x) {
        x = 20;
    }
}

a, x(λ§€κ°œλ³€μˆ˜)λŠ” μ§€μ—­ λ³€μˆ˜μ΄λ‹€.
μ§€μ—­ λ³€μˆ˜λŠ” 이름 κ·ΈλŒ€λ‘œ νŠΉμ • μ§€μ—­μ—μ„œλ§Œ μ‚¬μš©λ˜λŠ” λ³€μˆ˜λΌλŠ” λœ»μ΄λ‹€. 예λ₯Ό λ“€μ–΄μ„œ xλŠ” changePrimitive( ) λ©”μ„œλ“œμ˜ λΈ”λ‘μ—μ„œλ§Œ μ‚¬μš©λœλ‹€. changePrimitive( ) λ©”μ„œλ“œκ°€ λλ‚˜λ©΄ μ œκ±°λœλ‹€. a λ³€μˆ˜λ„ λ§ˆμ°¬κ°€μ§€μ΄λ‹€. main( ) λ©”μ„œλ“œκ°€ λλ‚˜λ©΄ μ œκ±°λœλ‹€.

λ³€μˆ˜μ˜ κ°’ μ΄ˆκΈ°ν™”

  • 멀버 λ³€μˆ˜ : μžλ™ μ΄ˆκΈ°ν™”
    • μΈμŠ€ν„΄μŠ€μ˜ 멀버 λ³€μˆ˜λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ μžλ™μœΌλ‘œ μ΄ˆκΈ°ν™”λœλ‹€.
    • 숫자(int) = 0, boolean = false, μ°Έμ‘°ν˜• = null(null 값은 μ°Έμ‘°ν•  λŒ€μƒμ΄ μ—†λ‹€λŠ” 뜻으둜 μ‚¬μš©λœλ‹€.)
    • κ°œλ°œμžκ°€ μ΄ˆκΈ°κ°’μ„ 직접 μ§€μ •ν•  수 μžˆλ‹€.
  • μ§€μ—­ λ³€μˆ˜ : μˆ˜λ™ μ΄ˆκΈ°ν™”
    • μ§€μ—­ λ³€μˆ˜λŠ” 항상 직접 μ΄ˆκΈ°ν™”ν•΄μ•Ό ν•œλ‹€.

InitData

package ref;

public class InitMain {
    public static void main(String[] args) {
        InitData initData = new InitData();
        System.out.println("value1 = " + initData.value1);
        System.out.println("value2 = " + initData.value2);
    }
}

value1은 μ΄ˆκΈ°κ°’μ„ μ§€μ •ν•˜μ§€ μ•Šμ•˜μ§€λ§Œ 멀버 λ³€μˆ˜λŠ” μžλ™μœΌλ‘œ μ΄ˆκΈ°ν™”λœλ‹€. μˆ«μžλŠ” 0으둜 μ΄ˆκΈ°ν™”λœλ‹€.
value2λŠ” 10으둜 μ΄ˆκΈ°κ°’μ„ μ§€μ •ν•΄λ‘μ—ˆκΈ° λ•Œλ¬Έμ— 객체λ₯Ό 생성할 λ•Œ 10으둜 μ΄ˆκΈ°ν™”λœλ‹€.

 

null

μ°Έμ‘°ν˜• λ³€μˆ˜μ—λŠ” 항상 객체가 μžˆλŠ” μœ„μΉ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” 참쑰값이 λ“€μ–΄κ°„λ‹€. 그런데 아직 κ°€λ¦¬ν‚€λŠ” λŒ€μƒμ΄ μ—†κ±°λ‚˜, κ°€λ¦¬ν‚€λŠ” λŒ€μƒμ„ λ‚˜μ€‘μ— μž…λ ₯ν•˜κ³  μ‹Άλ‹€λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒ?
μ°Έμ‘°ν˜• λ³€μˆ˜μ—μ„œ 아직 κ°€λ¦¬ν‚€λŠ” λŒ€μƒμ΄ μ—†λ‹€λ©΄ nullμ΄λΌλŠ” νŠΉλ³„ν•œ 값을 λ„£μ–΄λ‘˜ 수 μžˆλ‹€. null은 값이 μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”, μ—†λ‹€λŠ” λœ»μ΄λ‹€.

null κ°’ ν• λ‹Ή

package ref;

public class Data {
    int value;
}

NullMain1

package ref;

public class NullMain1 {
    public static void main(String[] args) {
        Data data = null;
        System.out.println("1. data = " + data);
        data = new Data();
        System.out.println("2. data = " + data);
        data = null;
        System.out.println("3. data = " + data);
    }
}

 

NullPointerException

λ§Œμ•½ μ°Έμ‘°κ°’ 없이 객체λ₯Ό μ°Ύμ•„κ°€λ©΄ μ–΄λ–€ λ¬Έμ œκ°€ λ°œμƒν• κΉŒ?
이 경우 NullpointerExceptionμ΄λΌλŠ” μ˜ˆμ™Έκ°€ λ°œμƒν•˜λŠ”λ°, 개발자λ₯Ό κ°€μž₯ 많이 κ΄΄λ‘­νžˆλŠ” μ˜ˆμ™Έμ΄λ‹€.
NullPointerException은 이름 κ·ΈλŒ€λ‘œ null을 가리킀닀(Pointer)인데, μ΄λ•Œ λ°œμƒν•˜λŠ” μ˜ˆμ™Έ(Exception)λ‹€. null은 μ—†λ‹€λŠ” λœ»μ΄λ―€λ‘œ κ²°κ΅­ μ£Όμ†Œκ°€ μ—†λŠ” 곳을 μ°Ύμ•„κ°ˆ λ•Œ λ°œμƒν•˜λŠ” μ˜ˆμ™Έμ΄λ‹€.

객체λ₯Ό μ°Έμ‘°ν•  λ•ŒλŠ” .(dot)을 μ‚¬μš©ν•œλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ 참쑰값을 μ‚¬μš©ν•΄μ„œ ν•΄λ‹Ή 객체λ₯Ό μ°Ύμ•„κ°ˆ 수 μžˆλ‹€. 그런데 참쑰값이 null이라면 값이 μ—†λ‹€λŠ” λœ»μ΄λ―€λ‘œ, μ°Ύμ•„κ°ˆ 수 μžˆλŠ” 객체(μΈμŠ€ν„΄μŠ€)κ°€ μ—†λ‹€. NullPointerException은 이처럼 null에 .(dot)을 μ°μ—ˆμ„ λ•Œ λ°œμƒν•œλ‹€.

package ref;

public class NullMain2 {
    public static void main(String[] args) {
        Data data = null;
        data.value = 10;  // NullPointerException μ˜ˆμ™Έ λ°œμƒ
        System.out.println("data = " + data.value);
    }
}

null 값은 μ°Έμ‘°ν•  μ£Όμ†Œκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” λœ»μ΄λ‹€. λ”°λΌμ„œ μ°Έμ‘°ν•  객체 μΈμŠ€ν„΄μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ λ‹€μŒκ³Ό 같이 java.lang.NullPointerException이 λ°œμƒν•˜κ³ , ν”„λ‘œκ·Έλž¨μ΄ μ’…λ£Œλœλ‹€.
참고둜 μ˜ˆμ™Έκ°€ λ°œμƒν–ˆκΈ° λ•Œλ¬Έμ— κ·Έ λ‹€μŒ λ‘œμ§μ€ μˆ˜ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.

멀버 λ³€μˆ˜μ™€ null

μ§€μ—­ λ³€μˆ˜μ˜ null 문제λ₯Ό νŒŒμ•…ν•˜λŠ” 것이 μ–΄λ ΅μ§€ μ•Šλ‹€. λ‹€μŒκ³Ό 같이 멀버 λ³€μˆ˜κ°€ null인 κ²½μš°μ—λŠ” μ£Όμ˜κ°€ ν•„μš”ν•˜λ‹€.

package ref;

public class NullMain3 {
    public static void main(String[] args) {
        BigData bigData = new BigData();
        System.out.println("bigData.count = " + bigData.count);
        System.out.println("bigData.data = " + bigData.data);

        System.out.println("bigData.data.value = " + bigData.data.value);
    }
}
  • bigData.countλ₯Ό 좜λ ₯ν•˜λ©΄ 0이 좜λ ₯λœλ‹€.
  • bigData.dataλ₯Ό 좜λ ₯ν•˜λ©΄ 참쑰값인 null이 좜λ ₯λœλ‹€. 이 λ³€μˆ˜λŠ” 아직 아무것도 μ°Έμ‘°ν•˜κ³  μžˆμ§€ μ•Šλ‹€.
  • bigData.data.valueλ₯Ό 좜λ ₯ν•˜λ©΄ data의 값이 nullμ΄λ―€λ‘œ null에 .(dot)을 찍게 되고, λ”°λΌμ„œ μ°Έμ‘°ν•  곳이 μ—†μœΌλ―€λ‘œ NullPointerException μ˜ˆμ™Έκ°€ λ°œμƒν•œλ‹€.
package ref;

public class NullMain4 {
    public static void main(String[] args) {
        BigData bigData = new BigData();
        bigData.data = new Data();
        
        System.out.println("bigData.count = " + bigData.count);
        System.out.println("bigData.data = " + bigData.data);

        // NullPointerException
        System.out.println("bigData.data.value = " + bigData.data.value);
    }
}

 

정리

λŒ€μ›μΉ™ : μžλ°”λŠ” 항상 λ³€μˆ˜μ˜ 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.

Javaμ—μ„œ λ³€μˆ˜μ— 값을 λŒ€μž…ν•˜λŠ” 것은 λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•˜λŠ” 것이닀.
κΈ°λ³Έν˜•, μ°Έμ‘°ν˜• λͺ¨λ‘ ν•­μƒ λ³€μˆ˜μ— μžˆλŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.
κΈ°λ³Έν˜•μ΄λ©΄ λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” μ‹€μ œ μ‚¬μš©ν•˜λŠ” 값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•˜κ³ , μ°Έμ‘°ν˜•이면 λ³€μˆ˜μ— λ“€μ–΄ μžˆλŠ” 참쑰값을 λ³΅μ‚¬ν•΄μ„œ λŒ€μž…ν•œλ‹€.
κΈ°λ³Έν˜•μ΄λ“  μ°Έμ‘°ν˜•μ΄λ“  λ³€μˆ˜μ˜ 값을 λŒ€μž…ν•˜λŠ” 방식은 κ°™λ‹€. ν•˜μ§€λ§Œ κΈ°λ³Έν˜•κ³Ό μ°Έμ‘°ν˜•μ— 따라 λ™μž‘ν•˜λŠ” 방식이 달라진닀.

κΈ°λ³Έν˜• vs μ°Έμ‘°ν˜• - κΈ°λ³Έ

  • μžλ°”μ˜ 데이터 νƒ€μž…μ„ κ°€μž₯ 크게 보면 κΈ°λ³Έν˜•κ³Ό μ°Έμ‘°ν˜•μœΌλ‘œ λ‚˜λˆŒ 수 μžˆλ‹€.
  • κΈ°λ³Έν˜•μ„ μ œμ™Έν•œ λ‚˜λ¨Έμ§€ λ³€μˆ˜λŠ” λͺ¨λ‘ μ°Έμ‘°ν˜•μ΄λ‹€. ν΄λž˜μŠ€μ™€ 배열을 λ‹€λ£¨λŠ” λ³€μˆ˜λŠ” μ°Έμ‘°ν˜•μ΄λ‹€.
  • κΈ°λ³Έν˜• λ³€μˆ˜λŠ” 값을 직접 μ €μž₯ν•˜μ§€λ§Œ, μ°Έμ‘°ν˜• λ³€μˆ˜λŠ” μ°Έμ‘°(μ£Όμ†Œ)λ₯Ό μ €μž₯ν•œλ‹€.
  • κΈ°λ³Έν˜• λ³€μˆ˜λŠ” μ‚°μˆ  연산을 μˆ˜ν–‰ν•  수 μžˆμ§€λ§Œ, μ°Έμ‘°ν˜• λ³€μˆ˜λŠ” μ‚°μˆ  연산을 μˆ˜ν–‰ν•  수 μ—†λ‹€.
  • κΈ°λ³Έν˜• λ³€μˆ˜λŠ” null을 ν• λ‹Ήν•  수 μ—†μ§€λ§Œ, μ°Έμ‘°ν˜• λ³€μˆ˜λŠ” null을 ν• λ‹Ήν•  수 μžˆλ‹€.

κΈ°λ³Έν˜• vs μ°Έμ‘°ν˜• - λŒ€μž…

  • κΈ°λ³Έν˜•κ³Ό μ°Έμ‘°ν˜• λͺ¨λ‘ λŒ€μž… μ‹œ λ³€μˆ˜ μ•ˆμ— μžˆλŠ” 값을 읽고 λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•œλ‹€.
  • κΈ°λ³Έν˜•μ€ μ‚¬μš©ν•˜λŠ” 값을 λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•˜κ³ , μ°Έμ‘°ν˜•μ€ 참쑰값을 λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•œλ‹€! μΈμŠ€ν„΄μŠ€λ₯Ό κ°€λ¦¬ν‚€λŠ” 참쑰값을 λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•˜λŠ” 것이닀!
    λ”°λΌμ„œ ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μ—¬λŸ¬ κ³³μ—μ„œ μ°Έμ‘°ν•  수 μžˆλ‹€.
  • λ³€μˆ˜μ— μ–΄λ–€ 값이 λ“€μ–΄μžˆλ“  간에 κ·Έ 값을 κ·ΈλŒ€λ‘œ λ³΅μ‚¬ν•΄μ„œ μ „λ‹¬ν•œλ‹€.

κΈ°λ³Έν˜• vs μ°Έμ‘°ν˜• - λ©”μ„œλ“œ 호좜

  • λ©”μ„œλ“œ ν˜ΈμΆœμ‹œ κΈ°λ³Έν˜•μ€ λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ λ§€κ°œλ³€μˆ˜(νŒŒλΌλ―Έν„°)의 값을 변경해도 호좜자의 λ³€μˆ˜ κ°’μ—λŠ” 영ν–₯이 μ—†λ‹€.
  • λ©”μ„œλ“œ ν˜ΈμΆœμ‹œ μ°Έμ‘°ν˜•μ€ λ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ λ§€κ°œλ³€μˆ˜(νŒŒλΌλ―Έν„°)둜 μ „λ‹¬λœ 객체의 멀버 λ³€μˆ˜λ₯Ό λ³€κ²½ν•˜λ©΄, 호좜자의 객체도 λ³€κ²½λœλ‹€.