국비지원

[JAVA] 221129 - 레퍼클래스, Exception, try catch, throw, GUI

yeon-96 2022. 11. 29. 22:44
반응형

Wrapper 클래스

서로 다른 타입의 자료형을 결합할 수 있도록 해주는 클래스
자바에서 다루는 기초형 타입들은 객체가 아니기에, 기본형 타입들을 객체로 만들어주는 클래스
ex) Integer 클래스의 parseInt, valueOf 메소드가 있다.

*스트링타입과 정수타입이 붙어버리는 상황이 발생

public class Main {

	public static void main(String[] args) {
		String numbers = "12345";
		System.out.println(numbers + 100);
        // 출력 값 : 12345100
        
       System.out.println(Integer.parseInt(numbers) + 100);
		System.out.println(Integer.valueOf(numbers) + 100);
        // 출력 값 : 12445
	}
}


*Integer.parseInt를 활용하여 numbers를 정수타입으로 바꿔줄 수 있다.


wrapper 클래스를 활용하여 기본형자료를 객체화 하는 것을 boxing(포장)이라고 부른다.
기본형자료를 포장하여 참조할 수 있게끔하고, 반대로 객체를 기본형자료로 바꾸는 것은 unboxing이다.

public class Main2 {
	public static void main(String[] args) {
		int primitive = 100;
		// 포장하여 객체의 형태로 !
		Integer ref = Integer.valueOf(primitive);
		int unbox = ref.intValue();
		
        // 손이 많이 가는 작업 !
		// 그래서 대입연산만으로도 표현가능 (편하게 쓰기위해 허용) auto-boxing, 오토박싱
		
        Integer ref2 = primitive;
		// unboxing
		int unbox2 = ref2;
		
		Boolean b = Boolean.valueOf("true");
		System.out.println(b);
		
		System.out.println(Integer.SIZE);
        // 자료형이 담기는 공간의 크기를 출력하는 문장
	}

}

<기본형의 박싱방법>
boolean - Booolean
char - Charcater
byte - Byte
short - Short
int - Integer
long - Long
float - Float
double - Double
*int와 char타입 외엔 첫글자를 대문자로 바꿔주기만하면된다.

Exception, try catch, throw

코딩을 하면 예외적인 상황이 무조건 발생하게 된다.(Exception)
흔히 출력되는 프로그램 종료 시 출력되는 붉은 문장들을 call stack이라고 부른다.(일종의 보고서)
메소드 호출의 흐름이 stack이라는 형태처럼 표현되고, stack의 젤 위는 가장 처음 실행 된 메소드며,
젤 아래에 있는 stack은 제일 처음 실행된 메소드다.

*기존의 예외를 처리하는 방법
조건문을 부여하여 예외적인 상황이 발생하지 않도록 제한을 걸었다.
하지만 이 방법은 프로그램이 예외 없이 정상적으로 흘러가는 것 처럼 보이게 하는 것일뿐이다.

*try catch문
try바디에는 실행시킬 문장을 넣고, catch바디에는 예외 발생 시 동작 될 문장을 넣어주면 된다.
흐름 : try에서 예외가 발생 > 첫 catch의 파라미터에 있는 예외가 발생 시 실행 > 아니다면, 그 다음 catch 파라미터 확인 후 바디 실행

public class Main {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		
		System.out.println("정수를 입력하세요.");
		try {
			int i = scan.nextInt(); 
			System.out.println(i);
		} catch (InputMismatchException e) {
			System.out.println("정수를 입력해주세요.");
		} catch (ArithmeticException e) {
			System.out.println("0으론 나눌 수 없습니다.");
		}
		System.out.println("정상 종료");
		
		
	}

}
//출력 값
정수를 입력하세요.
s
정수를 입력해주세요.
정상 종료

*finally 키워드
finally 블럭 : try와 catch에 상관없이 무조건 실행된다.
catch가 없어도 무조건 실행
finally블럭의 의미 : 동작을 끝내기위한 의미, 다른 프로세서가 사용할 수 있도록 .. 등등
예로 이클립스를 사용할 때 이클립스.exe는 삭제하거나 변경할 수 없다.

public class Main8 {
	public static void main(String[] args) {
		try {
			System.out.println("try 블럭");
			throw new Exception();
		} catch(RuntimeException e) {
			System.out.println("런타임 예외 처리 블럭");
		} catch(Exception e) {
			System.out.println("예외 처리 블럭");
		} finally {
			System.out.println("finally 블럭");
		}
	}
}
// 출력 값
//try 블럭
//예외 처리 블럭
//finally 블럭


*모든 예외를 잡고 싶다면 Exception e 활용? 그렇지 않다!
Exception클래스가 예외를 상속하는 최상위 클래스
자식으로만 예외를 잡아야 하는 이유
하나의 예외만 나오는게 아니고.
어떤 예외처리 방법으로 처리 되었는지 알 수 없기때문!
부모클래스 타입을 아래쪽 캐치에 넣어야한다.
자식 > 부모 차순
*Throw
throw 예외를 발생시키는 키워드
catch의 파라미터에는 부모의 타입이 들어가도 된다.

try {
			예외가발생할수있는메소드();
			throw new My런타임예외상속("런타임 예외 생성해보기");
		} catch (My런타임예외상속/*부모의 타입이 들어가도 됨*/ e) {
			System.out.println("내가 발생시킨 예외 처리하기");
			 e에서 어떤 것이 예외 되었는지 불러 올 수 있음
			System.out.println(e.getMessage());
			 콘솔창에 뜨는 빨간 문장을 출력해 볼 수 있음(흐름에 이상 없이 출력을 해주는 기능)
			e.printStackTrace();
		}
		System.out.println("프로그램 종료");
		
		 e == 예외 정보의 참조

printStackTrace();
콘솔창에 예외가 발생한 callstack을 출력해준다.

throw new
쓰로우 뉴 키워드로 강제로 예외적인 상황을 발생시킬 수 있다.

*method와 throws와의 관계
메소드 바디에 Excetion클래스를 상속받는 모든 클래스는 예외체크가 필요하다.(checked Exception)
발생시킨 시점에서 예외처리가 필요하지만, 메소드 파라미터 오른쪽에 throws 클래스명을 입력하게 되면
예외처리를 발생시킨 시점에서 체크하지않고 던지겠다 > 호출을 받겠다라는 의미가 된다.

public class Main6 {
	// 예외처리를 발생시킨 시점에서 하지않고 던지겠다 > throws (부모타입 명시가능)
	public static void 예외발생메소드() throws My예외상속 {
		System.out.println("메소드 호출");
		
		// Exception클래스를 상속받는 모든 클래스는 예외체크가 필요함 (checked Exception) 발생시킨 시점에서 예외처리가 필요함
		// RuntimeException클래스는 예외체크가 필요하지 않음(unchecked Exception)
		boolean 예외적상황 = true;
		if (예외적상황) {
			throw new My예외상속("예외 발생");
		}
		System.out.println("메소드 반환");
	}
	
	
	public static void main(String[] args) {
		try {
			예외발생메소드();
		} catch (My예외상속 e) {
			System.out.println("checked 예외처리");
		}
		
	}

}

main method에서 throws키워드가 포함 된 메소드가 trycatch문으로 예외체크 되고 있기에 Exception이 일어나지 않는 모습

*throw 활용 / 헤더는 픽스되었지만 바디가 미구현 되었을 때 활용하는 방법
출력을 통해 미구현되었다는 의도를 전달할 수 있다. 기존에 사용하던 조건문으로 예외체크를 하게 되면 메소드로 착각할수도 있다.

class asdf {
	public String somemethod() {
		// 헤더는 픽스되었지만 바디가 미구현 되었을 때 활용하는 방법
		throw new UnsupportedOperationException("미구현된 메소드입니다.");
	}
}


*throw new (Exception call stack) (문자열)
출력되는 call stack의 문장을 변경해 의도를 전달 할 수 있다.

class MySearchEngine {
	public static int indexOf(int search, int... arr) {
		if (arr == null || arr.length == 0) {
			throw new NoElementInArrayException("배열이 null참조이거나 원소가 없습니다.");
		}
		
		// 정수배열에서 정수 인덱스를 찾아 반환할 수 있는 메소드
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] == search) {
				return i;
			}
		}
		throw new NoSuchElementException("배열의 길이는 " + arr.length + "이지만 해당하는 " + search + "값 원소를 찾지 못했습니다.");
	}
}
public class Main7 {

	public static void main(String[] args) {
		int result = MySearchEngine.indexOf(78, 1,2,3,4,5);
		System.out.println(result);
		
		Scanner scan = new Scanner(System.in);
		// 만들어진 클래스의 메소드를 쓸 때 Throws도 확인하여 예외적인 상황에 대응해야함
		scan.nextInt();
	}

}
해당 예외 상황에서 한글로 문장이 변경된 것을 알 수 있다.

GUI

Graphical User Interface

GUI 단위는 pixel (px)이다.
사용자가 컴퓨터와 정보를 교환할 때, 그래픽을 통해 작업할 수 있는 환경을 말한다. 마우스 등을 이용하여 화면에 있는 메뉴를 선택하여 작업을 할 수 있다.
사용자가 그래픽을 통해 컴퓨터와 정보를 교환하는 작업 환경을 말한다.

import javax.swing.JFrame;

public class Main {

	public static void main(String[] args) {
		JFrame frame = new JFrame("처음 만든 창");
		frame.setSize(500, 500);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		
	}

}

Java swing 패키지에 JFrame이라는 창이 정의되어 있다.
창은 제목이라는 속성을 갖고 있고, 창의 구성요소를 Component (컴포넌트)라고 부른다.
setVIsible은 프로그램이 종료되지 않고 사용자 입력을 받을 수 있다.

*JFrame을 상속한 MyFrame 클래스의 흐름을 정리해보자 !

class MyClickEventListener implements ActionListener {
	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("사용자가 버튼을 눌렀습니다. 확인!");
	}
}
public class MyFrame extends JFrame {
	public MyFrame(String title) {
		super(title);
		Container container = getContentPane();
		
		container.setLayout(new FlowLayout());
		JButton button = new JButton("버튼");
		JButton button2 = new JButton("버튼2");
		container.add(button);
		container.add(button2);
		
		ActionListener listener = new MyClickEventListener();
		button.addActionListener(listener);
		button2.addActionListener(listener);
		
		setSize(500, 500);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}
	public void showGUI() {
		setVisible(true);
	}
	public static void main(String[] args) {
		MyFrame f = new MyFrame("내가 상속으로 만든 창");
		f.showGUI();
	}
}

1. 생성자 파라미터로 문자열형태 title값을 받아 부모클래스 생성자로 값을 넣어준다.
2. getContentPane메소드는 JFrame클래스의 객체메소드라 한다.
3. JButton을 활용해 버튼을 두개 생성하고, 버튼의 배치는 setLayOut(new FlowLayOut)이라는 레이아웃매니저가 하게 한다.
4. 컴포넌트들은 동작 될 때 마다 이벤트라는 비명을 지르는데, 그 이벤트를 들을 수 있도록 해주는 인스턴스를 생성해준다.
5. listener를각각의 버튼에 addActionListener메소드로 연결해준다.
6. 창은 setSize로 width와 height 값을 설정해주고, setDefaultCloseOperation(EXIT_ON_CLOSE);를 활용해 창의 닫기 버튼을 누르면 프로그램이 종료되도록 한다.
7.showGUI 메소드에는 setVisible값을 true로 줘서 창의 화면을 나타낼 수 있도록 해준다.
8. MyClickEventListener클래스를 만들어 implements ActionListener를 해준 후, actionPerformed(ActionEvent e) 메소드를 생성하고, 버튼을 클릭하였을 때 ActionEvent e에 매개변수가 들어가고 출력문장이 콘솔에 출력되는 것을 확인한다.


*버튼 클릭 시 창의 패널 백그라운드의 색상 변경 하기
처음 문제를 받았을 때 클래스가 나눠져 있고, JPanel 생성자 내에서 인스턴스가 생성되어 인스턴스를 참조하는 부분에서 고민이 많았는데, JPanel 변수를 필드로 빼고 나눠져있는 클래스를 메소드는 합쳐서 가져오고 implements도 덧 붙여 메소드에서도 JPanel 값에 접근 할 수 있도록 하였다.

public class ColorFrame extends JFrame implements ActionListener {
	JPanel pn1 = new JPanel();
	public ColorFrame() {
		super("색이 있는 창");
		// JPanel == 컨테이너 역할을 하는 도화지
		pn1.setBackground(new Color(0, 0, 0));
		add(pn1);
		JButton btn = new JButton("색 바꾸기");
		pn1.add(btn);
		Container container = getContentPane();
		btn.addActionListener(this);
		setSize(500, 500);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		int colorNum1 = (int)(Math.random() * 255) + 1;
		int colorNum2 = (int)(Math.random() * 255) + 1;
		int colorNum3 = (int)(Math.random() * 255) + 1;
		pn1.setBackground(new Color(colorNum1, colorNum2, colorNum3));
	}
	
	public void showGUI() {
		setVisible(true);
	}

	public static void main(String[] args) {
		new ColorFrame().showGUI();
	}
}
반응형