Today I Learned/2023

Java Switch NPE ํ”ผํ•˜๊ธฐ

YURI๐Ÿ•๐Ÿ“๐Ÿถ 2023. 1. 10. 18:40
๋ฐ˜์‘ํ˜•

Java Switch NPE ํ”ผํ•˜๊ธฐ

String str = null;

switch (str) {
    case "one":  
    	System.out.println("1");
    	break;
    case "two": 
    	System.out.println("2");
    	break;
    default:
    	System.out.println("default");
    	break;    
}
  1. ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ์—์„œ switch(์กฐ๊ฑด) -> (์กฐ๊ฑด)์— ๋“ค์–ด๊ฐ€๋Š” ๋ณ€์ˆ˜๊ฐ€ null์ผ ๊ฒฝ์šฐ NPE๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  2. ๋‹น์—ฐํ•œ ๊ฒฐ๊ณผ์ผ์ˆ˜๋„ ์žˆ์ง€๋งŒ, ์ƒ๊ฐ๋ณด๋‹ค ๋†“์น  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด๋ผ ๊ธ€๋กœ ๋‚จ๊ฒจ ๋†“์œผ๋ ค๊ณ  ํ•œ๋‹ค.
  3. ๋˜ํ•œ, NPE๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ• ๋ช‡๊ฐ€์ง€๋ฅผ ์†Œ๊ฐœํ•œ๋‹ค.
  4. ์‚ฌ์‹ค ๋‹ค ์ฉ ๋ง˜์— ๋“œ๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋ผ, Pattern Matching ๊ธฐ๋Šฅ์ด ๋„์ž…๋œ switch๋ฌธ์„ ์‚ฌ์šฉ(java 17 ์ดํ›„ ๋ฒ„์ „ ์‚ฌ์šฉ ๊ฐ€๋Šฅ. ๋‹จ preview ์ƒํƒœ)ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ๋ฉด NPE์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์—๋Š” if๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์˜ณ์•„ ๋ณด์ธ๋‹ค.

 

1. if ์‚ฌ์šฉ (์ด๋Ÿด๊ฑฐ๋ฉด ๊ทธ๋ƒฅ if๋ฌธ ์“ธ๊ฑธ..) 

null์ด๋ผ๋ฉด ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•œ ํ›„ switch๋ฌธ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

String str = null;

// default ๊ฐ’์œผ๋กœ ๋น ์ง€๊ฒŒ if๋ฌธ์—์„œ ๊ฐ’ ์ง€์ •ํ•ด์ฃผ๊ธฐ
if (str == null) {
	str = "default";
}

switch (str) {
    case "one":  
        System.out.println("1");
        break;
    case "two": 
        System.out.println("2");
        break;
    default:
        System.out.println("default");
        break;    
}

 

2. ์‚ผํ•ญ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ

null์ด๋ผ๋ฉด ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•œ ํ›„ switch๋ฌธ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

String str = null;

switch (str == null ? "NULL" : str) { // ์‚ผํ•ญ์—ฐ์‚ฐ์ž
    case "one":  
        System.out.println("1");
        break;
    case "two": 
        System.out.println("2");
        break;
    default:
        System.out.println("default");
        break;    
}

 

3. String.valueOf

String.valueOf ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด null ๊ฐ’์„ "null"๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

/**
 * Returns the string representation of the {@code Object} argument.
 *
 * @param   obj   an {@code Object}.
 * @return  if the argument is {@code null}, then a string equal to
 *          {@code "null"}; otherwise, the value of
 *          {@code obj.toString()} is returned.
 * @see     java.lang.Object#toString()
 */
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}
String str = null;

switch (String.valueOf(str)) { // ์‚ผํ•ญ์—ฐ์‚ฐ์ž
    case "one":  
        System.out.println("1");
        break;
    case "two": 
        System.out.println("2");
        break;
    case "null":
    default:
        System.out.println("default");
        break;    
}

 

4. pattern matching for switch (Java 17 - preview feature)

case ๋ฌธ์— null์ธ ๊ฒฝ์šฐ๋ฅผ ์ถ”๊ฐ€ํ•ด ํ•ด๊ฒฐํ•œ๋‹ค.

static void testFooBar(String s) {
    switch (s) {
        case null         -> System.out.println("Oops");
        case "Foo", "Bar" -> System.out.println("Great");
        default           -> System.out.println("Ok");
    }
}

static String formatterJava17(Object o) {
    return switch (o) {
        case Integer i -> String.format("int %d", i);
        case Long l    -> String.format("long %d", l);
        case Double d  -> String.format("double %f", d);
        case String s  -> String.format("String %s", s);
        default        -> o.toString();
    };
}

static void testTriangle2(Shape s) {
      switch (s) {
          case null ->
                  {}
          case Triangle t && (t.calculateArea() > 100) ->
                  System.out.println("Large triangle");
          case Triangle t ->
                  System.out.println("Triangle");
          default ->
                  System.out.println("Unknown!");
      }
  }

 

๐Ÿ‘ Reference

๋ฐ˜์‘ํ˜•