상세 컨텐츠

본문 제목

JAVA 업캐스팅, 다운캐스팅, instanceof 연산자

Spring/JAVA

by Chan.94 2022. 10. 17. 08:27

본문

반응형

캐스팅(Casting)

캐스팅이란 타입을 변환하는 것을 말하며 형 변환이라고도 한다.

자바의 상속 관계에 있는 부모와 자식 클래스 간에는 서로 간의 형 변환이 가능하다.

  • 업 캐스팅(Up Casting) : 자식 클래스가 부모 클래스의 타입으로 캐스팅
  • 다운 캐스팅(Down Casting) : 부모 클래스가 자식 클래스의 타입으로 캐스팅

 

개발을 하다보면 캐스팅하다가 오류가 종종 발생할 것이다. 특히 다운 캐스팅을 하다가 아래 ClassCastException을 마주하게 될 것이라 생각한다. 다운 캐스팅을 중점으로 정리하도록 하겠다.

java.lang.ClassCastException
다운 캐스팅은 업 캐스팅이 선행돼야 한다는 것을 기억하자.

Example

상속 구조

//부모 클래스
public class Trade {
	private String tradeDay;
	private String ip;
	
	public String getTradeDay() {
		return tradeDay;
	}
	public void setTradeDay(String tradeDay) {
		this.tradeDay = tradeDay;
	}
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}
}

//자식클래스1
public class StockTrade extends Trade{

	private String productName;

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}
}

//자식클래스2
public class BondTrade extends Trade{

	private String productName;

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}
}

Trade객체를 상속받는 StockTrade와 BondTrade가 있다.

 

업 캐스팅

public class CastingTestMain {
	public static void main(String[] args) {
		//업캐스팅 OK
		Trade trade = new StockTrade();
	}
}

업 캐스팅을 하는 데는 자주 실수하지 않을 것이다.


다운 캐스팅 Case(1)

public class CastingTestMain {
	public static void main(String[] args) {
		//case(1) 다운캐스팅 ClassCastException
		StockTrade trade = (StockTrade) new Trade();
	}
}

다운 캐스팅을 하면서 형 변환할 대상을 지정하여 컴파일 시점에 오류는 발생하지 않았다. 하지만 런타임 시점에는 오류가 발생할 것이다.

다운 캐스팅은 업캐스팅이 선행되야 한다는것을 기억하자.

다운캐스팅 Case(2)

public class CastingTestMain {
	public static void main(String[] args) {
		//case(2) 다운캐스팅 OK
		//Step1 - 업캐스팅
		Trade tradeCase2 = new StockTrade();
		//Step2 - 다운캐스팅
		StockTrade stockTrade = (StockTrade)tradeCase2;
		initTradeInfo(tradeCase2);
		System.out.println(String.format("case(2) [Down Casting] tradeDay : %s, ip : %s", stockTrade.getTradeDay(), stockTrade.getIp()));
	}
    
    public static Trade initTradeInfo(Trade trade) {
		Calendar calendar = Calendar.getInstance();
		Date date = calendar.getTime();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		trade.setTradeDay(sdf.format(date));
		trade.setIp("127.0.0.1");
		return trade;
	}
}

Step 1) StockTrade객체를 Trade객체로 업 캐스팅한다.

Step 2) StockTrade객체로 다운 캐스팅을 한다.

 

Output

case(2) [Down Casting] tradeDay : 2022-10-12, ip : 127.0.0.1

다운캐스팅 Case(3) - instanceof

public class CastingTestMain {
	public static void main(String[] args) {
		//case(3) 다운캐스팅 instandof 사용
		Trade tradeCase3 = new BondTrade();
		BondTrade bondTrade = (BondTrade)tradeCase3;
		initTradeInfo(tradeCase3);
		productSetting(tradeCase3);
		System.out.println(String.format("case(3) [Down Casting] tradeDay : %s, ip : %s, productName : %s", bondTrade.getTradeDay(), bondTrade.getIp(), bondTrade.getProductName()));
		
	}
	
	public static Trade initTradeInfo(Trade trade) {
		Calendar calendar = Calendar.getInstance();
		Date date = calendar.getTime();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		trade.setTradeDay(sdf.format(date));
		trade.setIp("127.0.0.1");
		return trade;
	}
	
	public static Trade productSetting(Trade trade) {
		if(trade instanceof StockTrade) {
			((StockTrade) trade).setProductName("삼성전자");
		}else if(trade instanceof BondTrade) {
			((BondTrade) trade).setProductName("삼성전자 회사채");
		}
		
		return trade;
	}
}

instanceof 연산자

객체의 타입을 구분하기 위해 instanceof 연산자를 사용한다.

 

Trade를 상속받는 StockTrade, BondTrade객체에 productName이라는 필드를 선언하였다. productSetting이라는 메서드는 매개변수로 Trade를 받기 때문에 어떤 객체로 생성됐는지 구분하기 위해서는 instanceof 연산자의 사용이 필요하다.

 

Output

case(3) [Down Casting] tradeDay : 2022-10-12, ip : 127.0.0.1, productName : 삼성전자 회사채

BondTrade로 다운 캐스팅했기 때문에 위와 같은 값이 설정된 것을 확인할 수 있다.

반응형

관련글 더보기

댓글 영역

>