머리말
Java를 배우는 과정에서 모든 사람들이 예외에 관한 장을 배웠다고 생각하며 여기에서 예외의 기본 특성과 사용에 대해서는 이야기하지 않을 것입니다. 예외는 무엇입니까? 모두가 어떻게 이해하는지 모르겠습니다. 내 이해는 매우 간단합니다. 즉, 비정상적인 상황입니다. 예를 들어, 나는 지금 남자이지만, 나는 여성에게 독특한 것이 있습니다. 제 생각에는 이것은 확실히 이상이며 나는 그것을 견딜 수 없습니다. 나는 모든 사람이 그것을 올바르게 이해하고 사용할 수 있다고 생각합니다.
그러나 광학 기본 예외 처리 및 사용이 불충분 한 경우 작업에서 발생하는 것은 무섭지 않습니다. 때로는 비즈니스 처리를 주도하기 위해 예외를 사용해야합니다. 예를 들어 : 고유 한 제약 조건이있는 데이터베이스를 사용하는 경우, 중복 데이터가 삽입되면 고유 한 제한 조건 예외 DuplickKeyException을 캡처하여 처리 할 수 있습니다. 이때, 해당 상태는 서버 계층의 호출 계층에 던져 질 수 있으며, 상부 레이어는 해당 상태에 따라이를 처리합니다. 따라서 때때로 예외는 비즈니스를위한 주행 방법입니다.
어떤 사람들은 예외를 포착 한 후에 예외를 출력합니다. 신중한 학생들이 무언가를 발견했는지 궁금합니다. 출력 예외는 무엇입니까?
다음은 일반적인 예외입니다.
java.lang.arithmeticexception : / by at greenhouse.exceptiontest.testexception.testexception (exceptiontest.java:16)에서 sun.reflect.nativemethodaccessorimpl.invoke0 (기본 방법)에서 sun.reflect.nativememedaDaccessorimpl.invoke (natodaccessorimpl.39). sun.reflect.delegatingMethodaccessorimpl.invoke (java.lang.reflect.method.invoke (method.java:597)의 Voke (위임 methodaccessorimpl.java:25) at org.junit.runners.model.frameworkmethod $ 1. org.junit.internal.runners.model.reflectiveCallable.run (reflectivecallable.java:15)의 runreflectiveCall (FrameworkMethod.java:44) org.junit.runners.model.frameworkmethod.invokeExplosively (frameworkmethod.java:41) at org.junit.internal.runners.invokemethod.evaluate (invokemethod.java:20) org.junit.runners.blockjunit4classrunner.runchild (org.junit.runners.blockjunit4classrunner.runchild (blockjunit4classrunner.java:50) at org.junit.runner.parentrunner $ 3.Run (parentrunner.java:193) at org.junit.runners.parentrunner $ 1.schedule (parentrunner.java:52) at org.junits.runners.parentrunner.runchildren (Parentrunner.java.191) org.junit.runner.ccacess $ 000 (parentrunner.java:42) at org.junit.runners.parentrunner $ 2.evaluate (parentrunner.java:184) at org.junits.runners.run.run (parentrunner.java:236) org.junit.runner.junitcore.run (junitcore.java:157) at com.intellij.junit4.junit4ideatestrunner.startrunnerwithargs (junit4ideatestrunner.java:68) at com.intellij.rt.execution.junit.ideatestrunner $ Repeater.startrunnerwithargs (ideatestrunner.java:47) at com.intellij.rt.execution.junit.junitstarter.preparestreamsandstart (junitstarter.java:242) at com.intellij.rt.execution.junit.junitstarter.main (junitstarter.java:70)
널 포인터 예외 :
java.lang.nullpointerexception at greenhouse.exceptiontest.testexception.testexception (exceptiontest.java:16)에서 sun.reflect.nativemethodaccessorimpl.invoke0 (기본 메소드)에서 sun.reflect.nativemethodaccessorimpl.invoke (nativemethodacccessorimpl.j.jeflect.nativemethodaccessorimpl sun.reflect.delegatingMethodaccessorimpl.invoke (java.lang.reflect.method.invoke (method.java:597)의 Voke (위임 methodaccessorimpl.java:25) at org.junit.runners.model.frameworkmethod $ 1. org.junit.internal.runners.model.reflectiveCallable.run (reflectivecallable.java:15)의 runreflectiveCall (FrameworkMethod.java:44) org.junit.runners.model.frameworkmethod.invokeExplosively (frameworkmethod.java:41) at org.junit.internal.runners.invokemethod.evaluate (invokemethod.java:20) org.junit.runners.blockjunit4classrunner.runchild (org.junit.runners.blockjunit4classrunner.runchild (blockjunit4classrunner.java:50) at org.junit.runner.parentrunner $ 3.Run (parentrunner.java:193) at org.junit.runners.parentrunner $ 1.schedule (parentrunner.java:52) at org.junits.runners.parentrunner.runchildren (Parentrunner.java.191) org.junit.runner.ccacess $ 000 (parentrunner.java:42) at org.junit.runners.parentrunner $ 2.evaluate (parentrunner.java:184) at org.junits.runners.run.run (parentrunner.java:236) org.junit.runner.junitcore.run (junitcore.java:157) at com.intellij.junit4.junit4ideatestrunner.startrunnerwithargs (junit4ideatestrunner.java:68) at com.intellij.rt.execution.junit.ideatestrunner $ Repeater.startrunnerwithargs (ideatestrunner.java:47) at com.intellij.rt.execution.junit.junitstarter.preparestreamsandstart (junitstarter.java:242) at com.intellij.rt.execution.junit.junitstarter.main (junitstarter.java:70)
예외의 출력이 예외가 정확하게 발생하는 위치이며 나중에 많은 실행 프로세스 호출이 인쇄 된 기능을 찾았습니까? 이 정보는 어디에서 왔습니까? 이 정보는 스택에서 얻습니다. 예외 로그를 인쇄 할 때이 통화 정보는 스택에서 얻습니다. 물론 예외를 정확하게 찾을 수있는 것이 좋지만 때로는 프로그램의 성능과 일부 요구 사항을 고려할 때이 정보를 완전히 인쇄 할 필요가 없으며 성능 소비 인 메소드 콜 스택에서 해당 정보를 얻을 필요가 없습니다. 고성능 요구 사항이있는 일부 프로그램의 경우이 측면에서 프로그램 성능을 완전히 향상시킬 수 있습니다.
그렇다면 이러한 스택 정보를 출력하는 방법은 무엇입니까? 그런 다음 사용자 정의 예외 가이 문제를 해결할 수 있습니다.
먼저 자동 예외는 runtimeexception을 상속 한 다음 FillInstackTrace 및 ToString 메소드를 다시 작성해야합니다. 예를 들어 아래에서 AppException 예외를 정의합니다.
package com.green.monitor.common.except; import java.text.messageformat;/*** 사용자 정의 예외 클래스*/public class appexception 확장 런타미 렉스 획득 {private boolean issuccess = false; 개인 문자열 키; 개인 문자열 정보; public appException (문자열 키) {super (키); this.key = 키; this.info = 키; } public appException (문자열 키, 문자열 메시지) {super (super (messageformat.format ( "{0} [{1}]", 키, 메시지)); this.key = 키; this.info = 메시지; } public appException (문자열 메시지, 문자열 키, 문자열 정보) {super (메시지); this.key = 키; this.info = info; } public boolean issuccess () {return issuccess; } public String getKey () {return 키; } public void setkey (문자열 키) {this.key = 키; } public String getInfo () {return info; } public void setInfo (문자열 정보) {this.info = info; } @override public trashable fillinstacktrace () {reture this; } @override public String toString () {return messageformat.format ( "{0} [{1}]", this.key, this.info); }}그렇다면 왜 fillinstacktrace 및 tostring 메소드를 다시 작성합니까? 먼저 소스 코드가 무엇인지 살펴 보겠습니다.
공개 클래스 runtimeexception 확장 예외 {static final long serialversionuid = -7034897190745766939L; /**는 <code> null </code>의 새 런타임 예외를* 세부 메시지로 구성합니다. 원인은 초기화되지 않으며 {@link #initcause}에 대한 호출로 이후에 초기화 될 수 있습니다. */ public runtimeexception () {super (); } /** 지정된 세부 사항 메시지로 새로운 런타임 예외를 구성합니다. * 원인은 초기화되지 않으며 * {@link #initcause}로 호출하여 초기화 될 수 있습니다. * * @param 메시지 세부 메시지. {@link #getmessage ()} 메소드에 의해 * 나중에 검색되면 세부 메시지가 저장됩니다. */ public runtimeexception (문자열 메시지) {super (메시지); } /** * 지정된 세부 메시지 및 * 원인으로 새로운 런타임 예외를 구성합니다. <p> * <code> 원인 </code>와 관련된 자세한 메시지는 <i> </i>이 런타임 예외의 세부 메시지에 자동으로 통합되지 않았습니다. * * @param 메시지 세부 메시지 ({@link #getmessage ()} 메소드에 의해 나중에 검색 *에 저장됩니다). * @param 원인 원인 ( * {@link #getCause ()} 메소드에 의해 나중에 검색되도록 저장). (a <tt> null </ tt> 값은 * 허용되며 원인이 존재하지 않거나 * 알 수 없음을 나타냅니다.) * @since 1.4 */ public runtimeexception (문자열 메시지, 던질 가능한 원인) {super (메시지, 원인); }/** 구성 지정된 원인과 <tt>의 * 세부 메시지 (원인 == null? null : again.toString ()) </tt> *의 새로운 런타임 예외입니다. 이 생성자는 런타임 예외 *에 유용합니다. * 다른 던지기의 포장지에 지나지 않습니다. * * @param은 원인을 유발합니다 ( * {@link #getCause ()} 메소드에 의해 나중에 검색되도록 저장). (a <tt> null </ tt> 값은 * 허용되며, 원인이 존재하지 않거나 * 알 수 없음을 나타냅니다.) * @since 1.4 */ public runtimeexception (Throwable Cause) {Super (원인); }}runtimeexception은 예외를 상속하지만 부모 클래스 메소드 만 호출하며 다른 작업을 수행하지 않습니다. 그럼, 예외에서 무슨 일이 일어나고 있는지 계속 봅시다.
공개 클래스 예외는 Throwable을 확장합니다 {정적 최종 Long SerialversionUid = -338751693124229948L; /*** <code> null </code>로 새로운 예외를 세부 메시지로 구성합니다. * 원인은 초기화되지 않았으며, {@link #initcause}에 대한 * 호출로 이후에 초기화 될 수 있습니다. */ public Exception () {super (); } /*** 지정된 세부 메시지로 새로운 예외를 구성합니다. * 원인은 초기화되지 않으며 {@link #initcause}에 대한 호출로 이후에 초기화 될 수 있습니다. * * @param 메시지 세부 메시지. {@link #getmessage ()} 메소드에 의해 * 나중에 검색되면 세부 메시지가 저장됩니다. */ public Exception (문자열 메시지) {super (메시지); } /** * 지정된 세부 메시지 및 * 원인으로 새로운 예외를 구성합니다. <p> * <code> 원인 </code>와 관련된 자세한 메시지는 <i> </i>이 예외의 세부 메시지에 자동으로 통합되지 않았습니다. * * @param 메시지 세부 메시지 ({@link #getmessage ()} 메소드에 의해 나중에 검색 *에 저장됩니다). * @param 원인 원인 ( * {@link #getCause ()} 메소드에 의해 나중에 검색되도록 저장). (a <tt> null </ tt> 값은 * 허용되며 원인이 존재하지 않거나 * 알 수 없음을 나타냅니다.) * @since 1.4 */ public Exception (문자열 메시지, 던질 가능한 원인) {super (메시지, 원인); }/** * 지정된 원인과 <tt>의 세부 메시지 * (원인 == null? null : as *이 생성자는 다른 던지기에 대한 * 포장지 이상의 예외에 유용합니다 (예 : {@link * java.security.privilegedactionException}). * * @param은 원인을 유발합니다 ( * {@link #getCause ()} 메소드에 의해 나중에 검색되도록 저장). (a <tt> null </ tt> 값은 * 허용되며 원인이 존재하지 않거나 * 알 수 없음을 나타냅니다.) * @since 1.4 */ public exception (Throwable Cause) {Super (원인); }}소스 코드에서 볼 수 있듯이 부모 클래스 메소드는 예외에서 직접 호출됩니다. runtimeexception처럼, 나는 실제로 아무것도하지 않았다. 그래서 던질 수있는 일에서 무슨 일이 일어나고 있는지 살펴 보겠습니다.
공개 클래스 던지기 가능한 구현 직렬화 가능 {public Throwable (String Message) {fillInstackTrace (); DetailMessage = 메시지; } /*** 실행 스택 추적을 채 웁니다. 이 메소드는이 * <code> Throwable </code> 현재 스레드의 스택 프레임의 현재 상태에 대한 객체 정보 내에 기록됩니다. * * @return이 <code> Throwable </code> 인스턴스에 대한 참조. * @ @see java.lang.throwable#printstacktrace () */ public synchronized 기본 던지기 가능한 fillinstacktrace (); /** * * {@link #printstacktrace ()}에 의해 인쇄 된 스택 추적 정보에 대한 프로그래밍 액세스를 제공합니다. 스택 추적 요소의 배열을 반환합니다. * 각각 하나의 스택 프레임을 나타냅니다. 배열 *의 Zeroth 요소 (배열 길이가 0이 아닌 것으로 가정)는 * 스택의 상단을 나타냅니다. 이는 시퀀스의 마지막 메소드 호출입니다. 일반적으로 * 이것은이 던지기가 만들어지고 던져진 지점입니다. * 배열의 마지막 요소 (배열 길이가 0이 아닌 것으로 가정) *는 스택의 바닥을 나타냅니다. 이는 순서대로 첫 번째 메소드 호출 *입니다. * * <p> 일부 가상 머신은 일부 상황에서 스택 추적에서 하나 이상의 스택 프레임을 생략 할 수 있습니다. 극단적 인 경우, *이 던질 수있는 스택 추적 정보가없는 가상 머신은이 * 메소드에서 제로 길이 배열을 반환 할 수 있습니다. 일반적 으로이 방법으로 반환 된 배열에는 * <tt> printstacktrace </tt>에 의해 인쇄 될 모든 프레임에 대해 하나의 요소가 포함됩니다. * * @return이 던지기와 관련된 스택 추적을 나타내는 스택 추적 요소의 배열. * @since 1.4 */ public stacktraceElement [] getStacktrace () {return (stackTraceElement []) getOrstackTrace (). clone (); } private synchronized stacktraceElement [] getourstacktrace () {// 스택 추적 초기화이 메소드의 첫 번째 호출 인 경우 (stacktrace == null) {int depth = getStackTracedEpth (); stacktrace = 새로운 stackTraceElement [깊이]; for (int i = 0; i <깊이; i ++) stacktrace [i] = getStackTraceElement (i); } 리턴 스택 트레이스; } /** * 스택 추적의 요소 수를 반환합니다 (또는 스택 * 트레이스를 사용할 수없는 경우 0). * * SharedSecrets에서 사용하기위한 패키지 보호. */ 기본 int getStacktracedEpth (); /*** 스택 추적의 지정된 요소를 반환합니다. * * SharedSecrets에서 사용하기위한 패키지 보호. * * * @Param 인덱스 요소의 인덱스 인덱스. * @throws indexOutOfBoundSexection <tt> index <0 || 인 경우 * index> = getStackTracePth () </ tt> */ avatile stacktraceElement getStacktraceElement (int index); /***이 던지기에 대한 간단한 설명을 반환합니다. * 결과는 다음과 같습니다. * <ul> * <li>이 개체의 클래스의 {@linkplain class #getName () name} : "(콜론 및 공간) * <li>이 개체의 {@link #getlocalizedMessage} * </ul> retly> * * if <tt> getLocalizedmessage </ul> <tt> null </tt>, 그 다음 * 클래스 이름이 반환됩니다. * * @return이 던질 수있는 문자열 표현. */ public String toString () {String s = getClass (). getName (); 문자열 메시지 = getLocalizedMessage (); return (메시지! = null)? (s + ":" + 메시지) : s; }소스 코드에서 거의 끝날 수 있습니다. fillinstacktrace () 메소드는 기본 메소드입니다. 이 방법은 기본 C 언어를 호출하고, 던질 수있는 객체 인 Tostring 방법을 반환하고, 던질 수있는 것에 대한 간단한 설명을 반환합니다. getStacktrace 메소드 및 getOrstackTrace에서 기본 메소드 getStackTraceElement가 호출됩니다. 이 메소드는 지정된 스택 요소 정보를 리턴 하므로이 프로세스는 성능을 소비해야합니다. 그런 다음 사용자 정의 예외에서 Tostring 메소드와 FillinstackTrace 메소드를 다시 작성하고 스택에서 예외 정보를 얻지 않고 직접 출력 할 수 있습니다. 이것은 시스템과 프로그램의 "무거운"것이 아니며 성능을 최적화하는 매우 좋은 방법입니다. 그렇다면 사용자 정의 예외가 발생하면 어떻게 생겼습니까? 아래를 참조하십시오 :
@Test public void testException () {try {String str = null; System.out.println (str.charat (0)); } catch (예외 e) {새로운 appException ( "000001", "null 포인터 예외"); }}그런 다음 예외가 비정상적이면 시스템은 맞춤형 예외 정보를 인쇄합니다.
000001 [NULL 포인터 예외] EXIT 코드 -1로 완료되었습니다
따라서 시스템 프로그램의 성능을 특히 간결하고 최적화하여 프로그램을 "무겁게"만들기 때문에 특수 성능 요구 사항이있는 시스템이 필요합니다. 서둘러 자신의 예외를 사용자 정의하십시오!
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.