throw와 throw new Exception ()의 차이점
차이점은 무엇입니까
try { ... }
catch{ throw }
과
try{ ... }
catch(Exception e) {throw new Exception(e.message) }
두 번째 메시지에 상관없이?
throw;
원래 예외를 다시 발생시키고 원래 스택 추적을 유지합니다.
throw ex;
원래 예외를 throw하지만 스택 추적을 재설정하여 catch
블록 까지 모든 스택 추적 정보를 삭제합니다 .
절대 쓰지 마throw ex;
throw new Exception(ex.Message);
더 나빠요 Exception
예외의 원래 스택 추적과 유형을 잃어 버린 새로운 인스턴스를 만듭니다 . (예 IOException
).
또한 일부 예외에는 추가 정보 (예 :)가 ArgumentException.ParamName
있습니다.
throw new Exception(ex.Message);
이 정보도 파괴됩니다.
경우에 따라 예외가 발생했을 때 코드가 수행 한 작업에 대한 추가 정보를 제공 할 수 있도록 모든 예외를 사용자 정의 예외 오브젝트로 랩핑 할 수 있습니다.
이렇게하려면 상속을하는 새로운 클래스를 정의 Exception
, 네 예외 생성자를 추가 및 소요 선택적으로 추가 생성자 InnerException
추가 정보뿐만 아니라,하고, 새로운 예외 클래스를 던져 통과 ex
는 AS InnerException
매개 변수 . original를 전달하면 InnerException
스택 추적을 포함하여 모든 원래 예외 속성이 유지됩니다.
첫 번째는 원래 스택 추적을 유지합니다.
try { ... }
catch
{
// Do something.
throw;
}
두 번째는 예외 유형 및 / 또는 메시지 및 기타 데이터를 변경할 수 있습니다.
try { ... } catch (Exception e)
{
throw new BarException("Something broke!");
}
내부 예외를 전달하는 세 번째 방법도 있습니다.
try { ... }
catch (FooException e) {
throw new BarException("foo", e);
}
다음을 사용하는 것이 좋습니다.
- 첫 번째는 정보를 파괴하거나 오류에 대한 정보를 추가하지 않고 오류 상황에서 일부 정리를 수행하려는 경우입니다.
- 세 번째는 오류에 대한 추가 정보를 추가하려는 경우입니다.
- 두 번째는 신뢰할 수없는 사용자로부터 정보를 숨기려는 경우입니다.
다른 사람이 보지 못한 한 가지 다른 점은 다음과 같습니다.
catch {} 블록에서 아무것도하지 않으면 try ... catch를 갖는 것은 의미가 없습니다. 나는 항상 이것을 본다 :
try
{
//Code here
}
catch
{
throw;
}
또는 더 나쁜 :
try
{
//Code here
}
catch(Exception ex)
{
throw ex;
}
최악의 경우 :
try
{
//Code here
}
catch(Exception ex)
{
throw new System.Exception(ex.Message);
}
throw
발견 된 예외 throw new Exception
의 세부 사항 중 일부 를 잃으면 서 스택 추적을 유지하면서 발견 된 예외를 다시 발생시킵니다.
일반적으로 throw
그 시점에서 예외를 완전히 처리하지 않고 자체적으로 예외를 기록합니다.
BlackWasp에는 C #에서 Throwing Exceptions 라는 제목의 기사가 있습니다.
새로운 예외를 던지면 현재 스택 추적이 사라집니다.
throw;
will retain the original stack trace and is almost always more useful. The exception to that rule is when you want to wrap the Exception in a custom Exception of your own. You should then do:
catch(Exception e)
{
throw new CustomException(customMessage, e);
}
throw
is for rethrowing a caught exception. This can be useful if you want to do something with the exception before passing it up the call chain.
Using throw
without any arguments preserves the call stack for debugging purposes.
If you want you can throw a new Exception, with the original one set as an inner exception.
Your second example will reset the exception's stack trace. The first most accurately preserves the origins of the exception. Also you've unwrapped the original type which is key in knowing what actually went wrong... If the second is required for functionality - e.g. To add extended info or re-wrap with special type such as a custom 'HandleableException' then just be sure that the InnerException property is set too!
Most important difference is that second expression erases type of exception. And exception type plays vital role in catching exceptions:
public void MyMethod ()
{
// both can throw IOException
try { foo(); } catch { throw; }
try { bar(); } catch(E) {throw new Exception(E.message); }
}
(...)
try {
MyMethod ();
} catch (IOException ex) {
Console.WriteLine ("Error with I/O"); // [1]
} catch (Exception ex) {
Console.WriteLine ("Other error"); // [2]
}
If foo()
throws IOException
, [1]
catch block will catch exception. But when bar()
throws IOException
, it will be converted to plain Exception
ant won't be caught by [1]
catch block.
throw or throw ex, both are used to throw or rethrow the exception, when you just simply log the error information and don't want to send any information back to the caller you simply log the error in catch and leave. But incase you want to send some meaningful information about the exception to the caller you use throw or throw ex. Now the difference between throw and throw ex is that throw preserves the stack trace and other information but throw ex creates a new exception object and hence the original stack trace is lost. So when should we use throw and throw e, There are still a few situations in which you might want to rethrow an exception like to reset the call stack information. For example, if the method is in a library and you want to hide the details of the library from the calling code, you don’t necessarily want the call stack to include information about private methods within the library. In that case, you could catch exceptions in the library’s public methods and then rethrow them so that the call stack begins at those public methods.
Throw; Rethrow the original exception and keep the exception type.
Throw new exception(); Rethrow the original exception type and reset the exception stack trace
Throw ex; Reset the exception stack trace and reset the exception type
None of the answers here show the difference, which could be helpful for folks struggling to understand the difference. Consider this sample code:
using System;
using System.Collections.Generic;
namespace ExceptionDemo
{
class Program
{
static void Main(string[] args)
{
void fail()
{
(null as string).Trim();
}
void bareThrow()
{
try
{
fail();
}
catch (Exception e)
{
throw;
}
}
void rethrow()
{
try
{
fail();
}
catch (Exception e)
{
throw e;
}
}
void innerThrow()
{
try
{
fail();
}
catch (Exception e)
{
throw new Exception("outer", e);
}
}
var cases = new Dictionary<string, Action>()
{
{ "Bare Throw:", bareThrow },
{ "Rethrow", rethrow },
{ "Inner Throw", innerThrow }
};
foreach (var c in cases)
{
Console.WriteLine(c.Key);
Console.WriteLine(new string('-', 40));
try
{
c.Value();
} catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
}
Which generates the following output:
Bare Throw:
----------------------------------------
System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<Main>g__fail|0_0() in C:\...\ExceptionDemo\Program.cs:line 12
at ExceptionDemo.Program.<>c.<Main>g__bareThrow|0_1() in C:\...\ExceptionDemo\Program.cs:line 19
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
Rethrow
----------------------------------------
System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<>c.<Main>g__rethrow|0_2() in C:\...\ExceptionDemo\Program.cs:line 35
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
Inner Throw
----------------------------------------
System.Exception: outer ---> System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<Main>g__fail|0_0() in C:\...\ExceptionDemo\Program.cs:line 12
at ExceptionDemo.Program.<>c.<Main>g__innerThrow|0_3() in C:\...\ExceptionDemo\Program.cs:line 43
--- End of inner exception stack trace ---
at ExceptionDemo.Program.<>c.<Main>g__innerThrow|0_3() in C:\...\ExceptionDemo\Program.cs:line 47
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
The bare throw, as indicated in the previous answers, clearly shows both the original line of code that failed (line 12) as well as the two other points active in the call stack when the exception occurred (lines 19 and 64).
The output of the re-throw case shows why it's a problem. When the exception is rethrown like this the exception won't include the original stack information. Note that only the throw e
(line 35) and outermost call stack point (line 64) are included. It would be difficult to track down the fail() method as the source of the problem if you throw exceptions this way.
The last case (innerThrow) is most elaborate and includes more information than either of the above. Since we're instantiating a new exception we get the chance to add contextual information (the "outer" message, here but we can also add to the .Data dictionary on the new exception) as well as preserving all of the information in the original exception (including help links, data dictionary, etc.).
참고URL : https://stackoverflow.com/questions/2999298/difference-between-throw-and-throw-new-exception
'development' 카테고리의 다른 글
가용성을 위해 HTTP URL을 핑하는 기본 Java 방법 (0) | 2020.06.07 |
---|---|
JavaScript를 사용하여 Ctrl + V, Ctrl + C를 감지하는 방법? (0) | 2020.06.07 |
일반 문자열과 완전 문자열의 차이점은 무엇입니까? (0) | 2020.06.07 |
SQL에서 테이블의 스키마 이름 변경 (0) | 2020.06.07 |
경고 : 내장 함수 'xyz'의 호환되지 않는 암시 적 선언 (0) | 2020.06.07 |