국비지원학원/Java

43일차

초코맛 2018. 12. 20. 23:11
반응형

컴파일 예외
런타임 예외
빼먹을 수가 없다.에러가나서
부모클래스가 런타임이 아닌 에러
개발자가 빼먹기 쉬움

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


 

 


반응형

'국비지원학원 > Java' 카테고리의 다른 글

47일차~50일차  (0) 2019.01.15
44~46일차  (0) 2019.01.14
42일차  (0) 2018.12.20
41일차  (0) 2018.12.20
40일차  (0) 2018.12.19