[JAVA] 221129 - 레퍼클래스, Exception, try catch, throw, GUI
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();
}
}