Java 9일차 : 내부클래스, 예외처리, 제너릭, 리스트
InstanceOf
- 클래스타입비교
[인스턴스명] instanceOf [클래스명]
- 해당 인스턴스가 [클래스명]타입이면 true를 반환
예시
package test.day0415;
class TestA{
public void writeA() {
System.out.println("writeA");
}
}
class TestB extends TestA{
private void wirte() {
System.out.println("sub writeA");
super.writeA();
}
public void writeB() {
System.out.println("writeB");
}
}
class TestC{
public void writeC() {
System.out.println("writeC");
}
}
public class InstanceOfEx1 {
public static void instanceTest(Object ob) {
System.out.println("TestA: " + (ob instanceof TestA));
System.out.println("TestB: " + (ob instanceof TestB));
System.out.println("TestC: " + (ob instanceof TestC));
System.out.println();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
TestA a = new TestA();
TestA a2 = new TestB();
TestB b= new TestB();
TestC c= new TestC();
instanceTest(a); //자기보다 큰 범위일때만 true, 즉 TestA만 true
instanceTest(a2); //TestA, TestB are true
instanceTest(b); //TestA, TestC are true
instanceTest(c); //Test C is true
}
}
내부클래스
-
일반 내부클래스 : 말 그대로 클래스 내부에 클래스가 있는것
class A{ class B{ } }
예시
package test.day0415; class OuterA{ int a = 10; static int b = 20; class InnerA{ int c = 30; // static int d = 40; //static class가 아닌 일반 내부클래스에서는 static 변수 사용불가 //외부클래스의 모든 변수 사용 가능 public void disp() { System.out.println("a= " + a); System.out.println("b= " + b); System.out.println("c= " + c); System.out.println("======="); } } //일반적으로 내부클래스의 메서드는 메인클래스가 아니라 외부클래스에서 호출한다. public void write() { InnerA a = new InnerA(); a.disp(); } } public class InnerClassEx2 { public static void main(String[] args) { OuterA a = new OuterA(); a.write(); //만약 메인클래스에서 타 클래스의 내부 클래스를 호출하고 싶다면? OuterA.InnerA b = new OuterA().new InnerA(); b.disp(); //혹은 OuterA.InnerA b = a.new InnerA(); 로 만들어도 좋다. 물론 의미는 좀 다르지만... OuterA.InnerA c = a.new InnerA(); a.a = 99; b.disp(); //여기에는 변수 a가 반영되지 않지만, c.disp(); //여기에는 변수 a가 반영된다. } }
실제로 저장될때는 OuterA.class 와 OuterA$InnerA.class로 저장됨
-
static 내부클래스
예시
package test.day0415; class OuterB{ int a= 10; static int b = 20; //static 내부클래스 내에서는 static변수 선언 가능 static class InnerB{ int c= 30; static int d=40; public void disp() { //System.out.println("a = " + a); //static 변수가 아닌 일반멤버변수는 호출이 안된다. System.out.println("b = " + b); System.out.println("c = " + c); //static클래스 내부의 일반변수는 static변수랑 같은건가? -> disp2 참고 System.out.println("d = " + d); System.out.println("========="); } public static void disp2() { //System.out.println("c = " + c); //static 클래스 내부의 일반 변수라고 해도 static 메서드에서 호출은 안됨. System.out.println("d = " + d); } } public void write() { InnerB ib = new InnerB(); ib.disp(); } } public class StaticInnerEx3 { public static void main(String[] args) { // TODO Auto-generated method stub OuterB ob = new OuterB(); ob.write(); //내부클래스가 static 클래스 일 때 직접 호출해보기 OuterB.InnerB inB = new OuterB.InnerB(); //내부클래스 앞에 new가 없다. inB.disp(); } }
-
익명 내부클래스
-
익명이란? 이름이 없는 것을 의미한다. 이것을 자바의 프로그램적으로 해석하면 정의된 클래스의 이름이 없다는 것이 된다.
- 내부 클래스긴 한데 새로 생성한것이 아니라, 타 클래스(인터페이스, 추상클래스 포함)를 생성해서 만든 클래스의 경우.
- 반드시 오브젝트 생성시 클래스명(); 으로 끝나지 않고, 클래스명() { 내용 }; 으로 진행되어야 생성됨.
예시
package test.day0415; interface Apple{ public void play(); } abstract class Apple2{ abstract public void draw(); } class Apple3{ public void run() { } } class Orange{ Apple ap = new Apple() { @Override public void play() { System.out.println("익명 내부 클래스의 메서드 실행 "); } }; Apple2 ap2 = new Apple2() { @Override public void draw() { System.out.println("추상 클래스로부터 만든 익명 내부 클래스 "); } }; Apple3 ap3 = new Apple3() { public void run() { System.out.println("일반클래스로 부터 익명내부클래스 생성하기 "); } }; } public class AnomInnerClassEx4 { public static void main(String[] args) { // TODO Auto-generated method stub Orange or = new Orange(); or.ap.play(); or.ap2.draw(); or.ap3.run(); } }
실제 파일은
Orange.class
Orange$1.class
Orange$2.class
Orange$3.class 로 생성된다.
-
지금까지 배운 클래스에 대한 활용법을 공부하기 위해서 간단하게 GUI 프로그래밍 스윙을 공부해보자
package test.day0415;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
class MyFrame extends JFrame implements WindowListener{
public MyFrame(String title) {
super(title); //JFrame의 생성자를 사용하자.
//시작위치 설정, 프레임의 너비와 높이 지정.
this.setLocation(300, 100);
this.setSize(800, 500);
//프레임 보이도록
this.setVisible(true);
this.addWindowListener(this);
}
@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
System.out.println("종료합니다.");
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
}
public class JframeSwingEx5 {
public static void main(String arg[]) {
MyFrame mf = new MyFrame("this is title!");
}
}
package test.day0415;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
class MyFrame2 extends JFrame{
public MyFrame2(String title) {
super(title); //JFrame의 생성자를 사용하자.
//시작위치 설정, 프레임의 너비와 높이 지정.
this.setLocation(300, 100);
this.setSize(800, 500);
//프레임 보이도록
this.setVisible(true);
this.addWindowListener(new WindowExit()); // 만들어둔 오브젝트가 없다면 그냥 인자줄때 생성해버리자~!
}
//내부클래스 - 더이상 상속이 힘들기 때문..
class WindowExit extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
System.out.println("종료합니다~!");
System.exit(0);
}
}
}
public class JframeSwingEx6 {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyFrame2 mf2 = new MyFrame2("this is title!");
}
}
Exception
-
일반적 예외 - ioexception => 반드시 처리
-
런타임 예외 - 실행시에 발생하는 exception
-
가장 많이 발생하는 예외
-
- NullPointerException : 객체 생성 없이 메서드를 호출할 때 발생
- ArrayIndexOutOfBounceException : 배열에서 없는 번지를 접근하려할때 발생
- NumberFormatException : Integer.parseInt(숫자 형태의 문자열을 정수타입으로 변환) 사용시에 많이 발생 (예 : 문자열에 공백이 포함되어 있거나 문자가 포함되어 있을 때)
형식
try{
exception이 발생할만한 로직
}catch(exception종류 e){
예외처리
}finally{
예외 상관없이 무조건 실행될 명령
}
예시
package test.day0415;
public class ExceptionEx7 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int arr[] = {4,5,6,8};
for( int i = 0 ; i <= arr.length ; i++) {
try {
System.out.println(arr[i]);
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("배열인덱스가 잘못되었다." + e.getMessage());
}
}
System.out.println("done!");
}
}
import java.sql.Date;
public class ExceotionEx8 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Date date = null;
String str = "12abc";
try {
date = new Date(2019,04,15);
System.out.println("연도출력");
System.out.println(date.getYear()); //여기서 예외발생 시 나머지 코드를 실행치 않고 바로 catch로 이동됨.
System.out.println("숫자변환");
int n = Integer.parseInt(str);
System.out.println(n);
}catch(NullPointerException e1) {
System.out.println("객체생성불가 " + e1.getMessage());
}catch(NumberFormatException e2) {
System.out.println("숫자변환시 문자가 섞여있음 " + e2.getMessage());
e2.printStackTrace();
}finally {
System.out.println("무조건 실행되는 명령");
}
System.out.println("bye!");
}
}
package test.day0415;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
class TestExcep{
public void test1() throws ArrayIndexOutOfBoundsException, IOException{ //요걸 붙히면 try에서 호출된 곳으로 예외처리를 미룰 수 있다.
int arr[] = {3,4,5,6};
for(int i = 0 ; i<= arr.length ; i++) {
System.out.println(arr[i]);
}
BufferedReader br = null;
InputStreamReader is = null;
br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("문자열을 입력하세요.");
String str = null;
str = br.readLine(); //일반적 예외는 반드시 throws를 클래스 선언시 넣거나, 해당 명령어에서 try/catch처리를 해줘야 한다.
System.out.println("입력한 문자열: " + str);
}
}
public class ExceptionEx9 {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestExcep ex = new TestExcep();
try {
ex.test1();
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println("배열인덱스오류 ");
} catch (IOException e) { //TestExcep 클래스에서 throws한 예외이므로 여기서 catch처리를 해준다.
// TODO Auto-generated catch block
System.out.println("IO예외");
e.printStackTrace();
}
System.out.println("bye!");
}
}
Throw
- 강제로 예외를 발생시킬 때 사용한다
package test.day0415;
import java.util.Scanner;
//사용자 예외 클래스 구현
class MyException extends Exception{
public MyException(String err) {
super(err);
}
public static void inputData() throws MyException
{
Scanner sc = new Scanner(System.in);
String str;
System.out.println("문자열 입력 ");
str = sc.nextLine();
if(str.contentEquals("바보")) {
throw new MyException("욕은 안돼요!!!"); //강제로 예외 발생
}else {
System.out.println("메세지는 " + str);
}
}
}
public class ExceptionEx10 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
MyException.inputData();
} catch (MyException e) {
// TODO Auto-generated catch block
System.out.println("오류메세지: " +e.getMessage()); //등록된 예외 메세지가 출력됨
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("bye!!");
}
}
제네릭
- 자료형에 어떤 객체를 담을지 명시
- Generics는 컬렉션(자료구조) 즉, 쉽게 말해서 객체들을 저장(수집)하는 구조적인 성격을 보강하기 위해 제공되는 것이다.
- 간단히 예를 들자면 컵이라는 특정 객체가 있다. 이 컵은 물만 담을 수 있는 물컵, 또는 이 컵은 주스만 담을 수 있는 주스 컵!이렇게 상징적인 것이 바로 Generics다!
Set
- Set 인터페이스를 상속받은 HashSet : 중복자료를 허용하지 않으며 비순차적으로 데이타를 저장
Set<형태> 변수명 = new HashSet<형태>();
- 주요 메서드 : add(object o), remove(index 혹은 object o), size()
package test.day0415;
import java.util.HashSet;
import java.util.Set;
public class SetEx11 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//<String> 제네릭 : String 타입만 담겠다.
Set<String> set = new HashSet<String>();
set.add("apple");
set.add("banana");
set.add("Apple");
set.add("apple"); //중복이므로 추가안됨
set.add("orange");
//set.add(100); //String타입이 아니므로 에러
System.out.println(set.size());
//set데이타 출력해보기
for(String s:set) {
System.out.println(s);
} //순서는 지맘대로....
Set<Integer> set2 = new HashSet<Integer>(); //뒤에는 반복해서 넣지말고 <>(); 라고만 해줘도 괜찮다.
int arr[] = {4,1,2,5,64,3,3,3};
for(int a:arr)
set2.add(a); //5.0이후버전에서는 에러없음 : 자동으로 객체화됨(오토박싱)
//5.0 이전버전에서는 set2.add(new Integer(a)); 라고 넣음
for(int s2:set2) {
System.out.println(s2);
}
set2.remove(4); //데이타 제거하기
System.out.println(set2.toString());
}
Map
- Map 인터페이스를 상속받은 클래스 HashMap : 키와 값의 쌍으로 저장하고자 할 때(이 때 키는 타입이 Set 으로 존재)
Map<K,V> map1 = new HashMap();
// 혹은
HashMap map2 = new HashMap2();
- 주요 메서드 : put(K, V), get(K), size()
리스트
- ArrayList / Vector가 있다 참고자료
package test.day0415;
import java.util.ArrayList;
import java.util.Vector;
public class ArrayListEx13 {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> list = new ArrayList<String>();
System.out.println(list.size());
list.add("apple");
list.add("banana");
list.add("kiwi");
list.add("banana");
System.out.println(list.toString()); //중복허용이며 순서대로 나온다. <-> Set
Vector<String> list2 = new Vector<String>();
System.out.println(list2.size());
System.out.println(list2.capacity()); //vector만 갖고있는 메서드
// 기본10개임. 선언시()안에 인자 줄 경우 그 수만큼 할당됨.
}
}
package test.day0415;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
public class VectorEx14 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//List<String> list = new Vector<String>(); //둘 중 뭘 써도 괜찮다.
List<String> list = new ArrayList<String>();
list.add("rose");
list.add("tulip");
list.add("daisy");
list.add("sunflower");
System.out.println("출력 1 ===========");
for(String l:list)
System.out.println(l);
System.out.println("출력 2 ===========");
for(int i = 0 ; i < list.size(); i++ ) {
System.out.println(list.get(i));
}
System.out.println("출력 3 ===========");
Iterator<String> iter = list.iterator();
while(iter.hasNext()) {//다음 데이타가 있으면 참
System.out.println(iter.next());
}
System.out.println();
list.remove(0); //0번째 데이타 삭제
System.out.println(list.toString());
list.add(1, "kanna"); //1번째 데이타로 삽입됨
System.out.println(list.toString());
list.clear(); //전체 삭제
System.out.println(list.toString());
}
}
-
여러개의 데이타를 클래스로 묶어서 Vector에 저장하는 예제를 해보자.
-
데이타 클래스는 뒤에 VO나 DTO를 붙여서 클래스명을 만든다.
package test.day0415;
import java.util.Date;
//데이타 클래스: 멤버변수는 모두 private
//생성자와 setter,getter 메소드로 구성
public class BoardDTO {
private String subject;
private String content;
private String writeDay;
public BoardDTO() {
// TODO Auto-generated constructor stub
}
public BoardDTO(String subject, String content, String writeDay) {
this.subject = subject;
this.content = content;
this.writeDay = writeDay;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getWriteDay() {
return writeDay;
}
public void setWriteDay(String writeDay) {
this.writeDay = writeDay;
}
}
Comments