반응형
컴파일 예외 |
런타임 예외 |
빼먹을 수가 없다.에러가나서
부모클래스가 런타임이 아닌 에러 |
개발자가 빼먹기 쉬움 |
package day1218;
/**
* Compile Exception : byte code를 정상적으로 생성하기 위한 것.
* 개발자가 반드시 예외상황을 처리해야하는 예외.(하지않으면 Error)
* @author owner
*/
public class UseCompileException {
public static void main(String[] args) {
//<다른클래스를 사용하려면 new 를 해야하는데, new 하지않고도 객체를 얻어 쓸수 있는 방법이있다.
//<forName(String className) 으로~! java.lang.reflect.Method?가 불러??
//<클래스가 없었을때의 (오타)의 경우를 대비해야한다.
try {
// Object obj/*Class c와 부모관계라 가능*/ =Class.forName("java.lang.String");
Object obj =Class.forName("day1217.UseRuntimeException");//sum사에서 만든것도,내가만든것도 가능.
//<ClassNotFoundException 처리해야~!한다~!Error
System.out.println("로딩한 클래스 "+obj);//new를 하지 않아도 객체를 얻어쓸수 있다.
} catch (ClassNotFoundException cnfe) {
System.err.println("죄송합니다.");//<사용자에게 에러에대한 정보를 제공하지 않는다.(악의적으로 사용할 수 있어서)
System.err.println("예외 메세지 출력 : "+cnfe.getMessage());
System.err.println("예외처리 객체외 메세지 : "+cnfe);
cnfe.printStackTrace();//<매우상세: stack에 담긴걸 추척해 출력, println과 같이 쓰면 나중에 쓰여도 출력순서가 꼬일수 있다.
// System.out.println("---5465465fgd65f");//<추척하는 과정이 더 느리기 때문
//pirntln은 printStackTrace보다 먼저 출력된다.
//<상세메세지 중에 내가작성한 클래스만 찾으면 된다.
//<<사용자에게는 "죄송합니다만" 나는 printStackTrace로 보고 운용시엔 지워준다~!~!
//<<런타임에러가 더 어렵고,예외처리 시에 블럭을 비워두면 의미가 없으니 잘처리해 준다.
}finally{
System.out.println("사용해 주셔서 ㄳㄳ");
}//end catch
}//main
}//class |
|
*컴파일 예외(Compile Exception)
- 에러처리중 오류메시지를 통한 정보노출 주의=>에러메세지가 아닌 문장으로 자세히도 말고!
*throws
-
예외 날림.
-
( 호출한곳에서 예외를 처리하게 된다. )
-
try~catch랑 많이 사용.
-
method header 뒤에 정의(method는 header와 body로 나눌수 있는데, 첫줄은 보통 헤더라고 하고, {} 중괄호부분을 바디(일하는부분)라고 함)
-
public void method(parameter,,,) thorws 예외처리객체명,,,
-
작성법)
-
접근지정자 반환형 method명(매개변수,,) thorws 예외처리클래스명,,,(필요한만큼 정의)
-
=>일을시키고 구분 =>예외처리 클래스명은 컴파일에러든,런타임에러든 섞든 상관이 없다.
-
method내에서 발생한 예외를 method를 호출한 곳(일을 사용하는곳)에서 처리하도록 만드는 것.
-
method내에서 try~catch를 할 필요가 없다 (try~finally만 사용=>꼭 실행될것)
-
예외가 발생했을때 처리코드를 업무로직에 대한 코드와 분리하여 정의할 수 있다.
-
장점 : (복잡도가 내려가고 유지보수성이 올라감, 유지보수업무와 일의구분)
-
호출한 곳에서 try~catch로 예외처리를 하게된다.
-
ex)
-
PM/*관리자가 유능할수록 잘다룬다.*/{
-
try{
-
이재현();
-
}catch(열받음){
-
술사줌;
-
}
-
}//호출하는 부분 class
-
-
public void 이재현() thorws 열받음{ //사용한곳에서 처리해 준다.(던져)
-
업무과중;
-
}
-
일많아서 힘들어도 괜찮아~!~!보단 그냥 잘포장해 얘기 해~!~! 잘타개해야한다~!
-
=>이 일을 하면 어떤 문제가 발생하니 대비코드 (처리) 해야지=>Throws
-
=>명확하게 예외처리클래스명을 밝혀야 한다.(상위ㄴㄴ하위 클래스ㅇㅇ)
-
=>Exception은 "오빠,뭐땜에 화난지 몰라?"임.. 명확하게 콕찝어 주어야 한다.
-
복사(copy):A4용지 똑같이 만든것(무생물) vs 복제(clone):사람을 똑같이만든것(살아있는것)
-
=>자바는 객체를 살아있는것으로 본것.
-
컴파일 예외 (부모에 Runtime이 없다)
-
여러개의 예외도 있다.
package day1218;
import java.util.Random;
/**
* throws)
* method내에서 발생한 예외를 method를 호출한 곳에서 처리하는 throws의 사용.
* @author owner
*/
public class UseThrows{
public void test() throws ClassNotFoundException {
//throws로 예외를 날리면 method안에 try~catch를 할 필요가 없다.
String className="day1217.UseRuntimeException";
// System.out.println("클래스 field : "+obj);
if(new Random().nextBoolean()) {
className="java.lang.Integer";
}//end if
Object obj=Class.forName(className);
System.out.println("클래스가 로딩되었습니다. "+obj);
}//test
public static void main(String[] args) {
UseThrows ut=new UseThrows();
try {
ut.test();//method를 호출하여 일을 수행하다보면 문제가 발생할 수도 있다.=>try~catch
} catch (ClassNotFoundException cnfe) {
System.err.println("죄송합니다.");
cnfe.printStackTrace();
System.out.println("정상출력");
}//end catch
}//main
}//class
<<예외를 날린부모는 자식에서도 예외처리>>
package day1218;
/**
* 생성자에서 예외를 날리는 경우
* @author owner
*/
public class ConstructorThrows {
public ConstructorThrows() throws ClassNotFoundException{
Class.forName("java.lang.Object");
System.out.println("객체 생성");
}//ConstructorThrows
public static void main(String[] args) {
try {
ConstructorThrows ct = new ConstructorThrows();
System.out.println("객체화 성공 : " +ct);
} catch (ClassNotFoundException cnfe) {
System.out.println("객체화 중 에러 발생!!!");
}//end catch
}//main
}//class
package day1218;
public class ConstructorThrowsSub extends ConstructorThrows{
//부모클래스의 생성자가 컴파일 예외를 날리면 자식클래스의 생성자에서도 (같은?)예외를 날려야 한다. <<상속이면~!>>
public ConstructorThrowsSub() throws ClassNotFoundException {
// super();//여기서의 try~catch는 super가 첫번째 줄이 안돼기 때문에 던져주어야 한다.
// try {
// super();//super는 생성자의 첫번째 줄에서만 기술할 수 있으므로 부모클래스의 생성자가 Compile Exception을 throws로 날리면
//생성자를 호출하는 자식클래스에서는 반드시 예외를 처리해야하는 문법상 에러가 발생하게 된다.
// }catch(ClassNotFoundException cnfe) {
//
// }
super();
//<생성자에서 예외처리하는 경우는 많이 없지만 하게된다면 자식에서도 해주어야 한다.
}//ConstructorThrowsSub
public static void main(String[] args) {
}//main
}//class
*객체 복제
-
<객체는 복제가 된다..!(모든객체가 복제가 가능한데 안된다?)
-
모든 객체는 복제될 수 있는 method(잠재적인 기능)을 갖고있다. ( java.Object.clone() )=>왜복제해야 할까..복제되는 상황은 언제일까?
-
변화된 상태를 저장하기 위해서 복제한다. (객체는 주소를 가지는데, 딱한개의 주소가 만들어진다. (주소넘김) call by reference)
-
Stack에 객체를 넣을때 컨트롤+z로 취소=>히스토리!! 객체를 담으면 주소가 어떻게 하나가 나오는 걸까?일 때.
-
복제는 되지 않는다.(복제를 하려면 복제를 해도 된다는 검증?확인?이 있어야 한다.=>Cloneable(데이터형을 확인하는 목적으로만 쓰임)
-
(Cloneable 이라고 하는 interface만 구현한 객체만 복제가 된다.)
-
+Object
-
-
#(protected)Clone:Object<- +MyClass - - >+Cloneable: 데이터형을 확인할 목적으로 만드는 interface(확인용)
-
Serializable : 잘려질수 있어........(허가) : class니 method니 아무것도 없다..이것과 비슷한 역할
-
Myclass mc = new Myclass();//원본
-
Myclass o1/*이전상태, 복제된 객체*/=(MyClass)mc.clone();/*mc는 복제된 객체*/
-
-
try(
-
Myclass mc = new Myclass();
-
}catch(cloneNotSuportedException){
-
ㅈㅅ;
-
}
-
//히스토리를 남겨야 하는상황에 객체를 복제하여 남겨둔다~!~!
복제되는 객체는 Cloneable interface를 구현해야만 한다.
//clone()은 protected접근지정자를 가지고 있어 외부클래스에서
//다른클래스의 clone()을 호출할 수 없다.복제한것을 내어 주어야 한다~!
-
번외)
-
instanceof : 연산자 (객체가 이클래스로 부터 만들어졌는가를 비교한다.)
-
:생성된 객체가 특정 클래스(interface)로부터 나왔는지 비교할 때 사용.=>True,False로 나온다.
-
문법 : 객체명 instanceof 클래스명|인터페이스명 =>
-
ex : Myclass mc=new MyClass();
-
if(mc instanceof Cloneable){ //
-
mc가 cloneable과 is a 관계인경우
-
}else{
-
mc가 cloneable과 is a 관계가 아닌경우
-
}//end else
-
인터퍼이스를 구현한 클래스가 여러개인데, 특정 클래스를 부모로 할때 객체가 어느 객체냐 에 쓰임
-
사진 참조~!
*Throw : 예외 강제 발생
-
<예외를 강제로 발생
-
특정 조건에 일치하면 예외를 강제로 발생시켜 처리하는 것.
-
강제발생된 예외는 반드시 try~catch로 처리하든 throws로 예외를 날리던가 처리 해야한다.(throws가 훨씬 많이 쓰임)
-
사용자정의 예외 처리 클래스와 주로 사용.
-
문법)
-
throw new 예외처리클래스();
-
//로 처리. 무조건 까지는 아니라 if 에 넣어 사용하게 된다.
-
ex)
-
public void test() throws Exception/*밖에서도 알수 있다.*/{
-
-
try{
-
if(조건식){
-
throw new Exception(String); //여기에 넣는 String는printStackTrace?에? 나온다?
-
}
-
}catch(Exception){
-
예외처리;
-
}//밖에서 뭐땜에 예외처리했는지? 예외처리를 안했는지 모른다
-
//throw가 처음! 터지고 날려서 처리해~!~!
-
public void login(String id,String pass){
-
//id가 admin이고 pass가 123일때 로그인 처리
-
//성공vs실패를 가지는데 성공했을때에만 갖고 실패를 분리하고 싶다.
-
if(id.equals("admin")&&pass.equals("123")){
-
성공
-
}else{
-
throw new LoginFailException();//날린다.
-
}
-
-
public void login(String id,String pass) throws LoginFailException{ //LoginFailException 내업무에 필요한 예외..를 업무에 맞게 만들어야함.
-
//id가 admin이고 pass가 123일때 로그인 처리
-
//성공vs실패를 가지는데 성공했을때에만 갖고 실패를 분리하고 싶다.
-
if(id.equals("admin")&&pass.equals("123")){
-
성공
-
}else{
-
throw new LoginFailException();//날린다.
-
}
-
}
-
//호출한 부분
-
try{
-
login("test","123");
-
}catch(LoginFailException lfo){
-
//로그인 실패 했을때 코드
-
}
*사용자 정의 예외 처리 클래스
-
업무에 맞는 예외처리 클래스가 없다면 그 예외체리클래스를 개발자가 이름을 부여해서 만드는 것.
-
Exception을 상속받거나 RuntimeException을 상속받아서 만든다.
<<어제자 숙제 문제 풀이>>
package day1218;
public class ScoreVO {
private String name;
private int javaScore,oracleScore;
public ScoreVO(String name, int javaScore, int oracleScore) {
super();
this.name = name;
this.javaScore = javaScore;
this.oracleScore = oracleScore;
}//ScoreVO
public String getName() {
return name;
}
public int getJavaScore() {
return javaScore;
}
public int getOracleScore() {
return oracleScore;
}
}//class
package day1218;
import static java.lang.Integer.parseInt;//parseInt만 쓰면 되게끔 만들어 준다.
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
public class ScoreProcess {
private List<ScoreVO> listStu;
private int totalScore;
public static final int INPUT_DATA=1;
public static final int VIEW_DATA=2;
public static final int EXIT=3;
public ScoreProcess() {
listStu=new ArrayList<ScoreVO>();//인스턴스화
}//ScoreProcess
/**
* 선택메뉴를 제공하는 일
*/
public void inputMenu() {
String selectMenu="",inputResult="";
boolean exitFlag=false;//불린을 하나 만들어서 3일때만 나가게
do {//계속 나와야 돌아야 하는지라 무조건 제시도 1번 되어야 하고
selectMenu=JOptionPane.showInputDialog("메뉴 선택\n1.입력 2.출력 3.종료");
// if(selectMenu.equals("3")) {
// exitFlag=true; //flag변수를 만들어서 3이면 ture로 ture일때 나가게 만들어도 된다.
//// break;//으로 반복문을 나가도 되지만
// }
// exitFlag=selectMenu.equals("3");//한줄로도 가능해 진다~!~!
try {
switch (parseInt(selectMenu/*String니까 integer로*/)) {
case INPUT_DATA:
// inputData(); break;
inputResult="데이터의 갯수가 맞지 않거나, 점수는 숫자형태이어야 합니다.";
if(inputData()) {
inputResult="추가성공";
}//end if
JOptionPane.showMessageDialog(null, inputResult);
break;
case VIEW_DATA:
printData(); break;
case EXIT:
exitFlag=true; break;
default:
JOptionPane.showMessageDialog(null, "메뉴는 1,2,3중 하나 이어야만 합니다.");
}//end switch
}catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(null, "메뉴는 숫자 이어야 합니다.");
}//end catch
}while(/*true*/!exitFlag);
}//inputMenu
/**
* 정보처리할 데이터를 입력받는 일
* @return
*/
public boolean inputData() {
boolean flag=false;
String inputData=JOptionPane.showInputDialog("데이터 입력\n예) 이름, 자바점수, 오라클점수");
try {//취소누르면 nullpoint떠...
String[] data=inputData.replaceAll(" ", "").split(",");//<공백없애주고 컴마에서 잘라쥬
if(data.length==3) { //입력형식에 맞을 때
try {
ScoreVO sv=new ScoreVO(data[0], parseInt(data[1]), parseInt(data[2]));
listStu.add(sv);//정제된 데이터를 list에 추가
flag=true;//실행 결과를 저장.
//자바점수와 오라클점수는 숫자 이어야 한다.
}catch (NumberFormatException nfe) {
JOptionPane.showMessageDialog(null, "자바점수와 오라클점수는 숫자 이어야 합니다.");
flag=false;
}//end catch
}//end if
}catch (NullPointerException npe) {
}//end catch
return flag;
}//inputData
/**
* 입력정보를 출력하는 일
*/
public void printData() {
if(listStu.size()==0) {
JOptionPane.showMessageDialog(null, "출력할 데이터가 없습니다.");
return;//아래로 흘러가지 않게
}//end if
StringBuilder viewData=new StringBuilder();
viewData
.append("-----------------------------------------\n")
.append("번호\t이름\t자바\t오라클\t총점\t평균\n")
.append("-----------------------------------------\n");
int tempTotal=0;
ScoreVO sv=null;
for(int i=0;i<listStu.size();i++) {
sv=listStu.get(i);
tempTotal=sv.getJavaScore()+sv.getOracleScore();
viewData.append(i+1).append("\t").append(sv.getName())
.append("\t").append(sv.getJavaScore())
.append("\t").append(sv.getOracleScore()).append("\t").append(tempTotal)
.append("\t").append(tempTotal/2.0).append("\n");
totalScore+=tempTotal;//한 학생의 자바점수와 오라클 점수를 더한 값을 누적합.
tempTotal=0;//한 학생의 총점 변수를 초기화
}//end for
// DecimalFormat df = new DecimalFormat("00.00");
viewData.append("-----------------------------------------\n")
.append("\t\t\t\t총점").append(totalScore).append("\t평균")
.append(String.format("%5.2f",totalScore/((double)listStu.size()*2)));
//value Arguments 실수) "%전체자릿수.실수자릿수f"
JTextArea jta=new JTextArea(7,50);
jta.append(/*String.valueOf(viewData)*/viewData.toString());//화면을 구성한 데이터를 JTA에 붙여준다.
JScrollPane jsp=new JScrollPane(jta);
JOptionPane.showMessageDialog(null, jsp);
}//printData
public static void main(String[] args) {
ScoreProcess sp =new ScoreProcess();
sp.inputMenu();
}//main
}//class
반응형