在方法内部throw异常，必须要同时在方法头部声明throws吗？
下面节选自类 JSONObject:
```
public String getString(String key) {
    this.verifyIsNull();
    Object o = this.get(key);
    if(o != null) {
        return o.toString();
    } else {
        throw new JSONException("JSONObject[" + JSONUtils.quote(key) + "] not    found.");
    }
}
```
以上直接抛出异常，而没有在方法头部声明throws。
但是我自己写的方法中，是同时有throw和throws的。去掉throws就会报错：
Unhundled Exception 。
这是为什么？
java异常一般分为`Checked`异常和`Runtime`异常，所有`RuntimeException`类及其子类的实例被称为`Runtime`异常，不属于该范畴的异常则被称为`CheckedException`。
Java认为`Checked`异常都是可以被处理的异常，所以Java程序必须显示处理Checked异常。如果程序没有处理`Checked`异常，该程序在编译时就会发生错误无法编译。
而`RuntimeException`异常如果没有显示的捕获处理则由系统自动检测并将它们交给缺省的异常处理程序。
`JSONException`应该是`RuntimeException`的子类，可以不用显式的对它try...catch或者throws.如果没有对该异常的处理会交给jvm处理。
而你自己写的异常肯定是属于Checked异常，被认为是可以避免的异常，必须try...catch或者显式的抛出throws不然编译报错。如果你自定义的异常想像`throw new JSONException`这样处理，则你自定义的异常需要继承`RuntimeException`即可。