# 构造器可以声明初始化器块中引发的受检异常

> 原文： [https://howtodoinjava.com/java/exception-handling/checked-exceptions-thrown-in-initializer-blocks-can-be-declared-by-the-constructors/](https://howtodoinjava.com/java/exception-handling/checked-exceptions-thrown-in-initializer-blocks-can-be-declared-by-the-constructors/)

这篇文章是对 [**Java**](//howtodoinjava.com/tag/java-hidden-features/ "java hidden features") 鲜为人知的特性的继续。 在上一篇文章中，我介绍了“[**相同类的实例可以访问彼此的私有成员**](//howtodoinjava.com/object-oriented/instances-of-same-class-can-access-private-members-of-each-other/ "Instances of same class can access private members of each other")”，以及一些非常令人惊讶的[**`sun.misc.Unsafe`类的用法**](//howtodoinjava.com/java/related-concepts/usage-of-class-sun-misc-unsafe/ "Usage of class sun.misc.Unsafe")。 在本文中，我将讨论一个关于初始化块的鲜为人知的特性。

初始化块是括号之间的代码块，该代码块在创建类实例之前甚至在调用构造器之前执行。 完全没有必要将它们包括在您的类中。

初始化器可以通过两种方式使用：

**1）非静态初始化器块**

它取决于对象，并且为创建的类的每个对象执行初始化块。 它可以初始化类的实例成员变量。

**2）静态初始化器块**

它使用关键字`static`定义，并且在加载类时执行一次，并且有限制，它只能初始化类的静态数据成员。

这就是我们所知道的。 现在进入我们很多人以前都不知道的部分。

有时，在初始化器块中，您可能需要编写一些代码，这些代码可能引发受检异常。 受检异常是那些在编译时受检异常，编译器会强制您在代码中处理它们。 让我们举个例子：

```java
	public class CheckedExceptionsFromConstrctor {
		Document doc = null;
		{
			doc = new SAXBuilder(false).build(new StringReader(new String("<users/>")));
		}
	}

```

**上面的代码引发了两个受检的异常**`IOException`和`JDOMException`。您可以使用`try-catch`处理它们。 例如：

```java
	{
		try {
			doc = new SAXBuilder(false).build(new StringReader(new String("<users/>")));
		} catch (JDOMException | IOException e) {
			e.printStackTrace();
		}
	}

```

如果您不希望在初始化器中处理异常并尝试抛出该异常，则编译器将不允许您这样做。

```java
	{
		try {
			doc = new SAXBuilder(false).build(new StringReader(new String("<users/>")));
		} catch (JDOMException | IOException e) {
			throw e;								//Not allowed
		}
	}

```

**解决方案：在所有构造器中为所有受检异常添加`throws`子句**

在构造器中添加`throws`子句，您将可以从初始化器中抛出受检异常。 例如

```java
public class CheckedExceptionsFromConstrctor
{
	Document doc = null;
	public CheckedExceptionsFromConstrctor() throws IOException, JDOMException
	{
		//Some other code
	}
	public CheckedExceptionsFromConstrctor(String s) throws IOException, JDOMException
	{
		//Some other code
	}
	{
		doc = new SAXBuilder(false).build(new StringReader(new String("<users/>")));
	}
}

```

或者：

```java
public class CheckedExceptionsFromConstrctor
{
	Document doc = null;
	public CheckedExceptionsFromConstrctor() throws IOException, JDOMException
	{
		//Some other code
	}
	public CheckedExceptionsFromConstrctor(String s) throws IOException, JDOMException
	{
		//Some other code
	}
	{
		try {
			doc = new SAXBuilder(false).build(new StringReader(new String("<users/>")));
		} catch (JDOMException | IOException e) {
			throw e;
		}
	}
}

```

以上两种解决方案均有效，编译器将允许您执行此操作。

**静态初始化器无法引发受检异常**

上面的推理是针对非静态初始化器的。 如果您的类中有静态初始化器，则必须处理受检异常。 您不得以任何可能的方式扔它们。

```java
public class CheckedExceptionsFromConstrctor
{
	static Document doc = null;
	public CheckedExceptionsFromConstrctor() 
	{
		//Some other code
	}
	static {
		try {
			doc = new SAXBuilder(false).build(new StringReader(new String("<users/>")));
		} catch (JDOMException | IOException e) {
			e.printStackTrace();				//You must handle the exception here
		}
	}
}

```

就是这个话题。 希望你喜欢它。 如果您在评论部分有任何想法，我们将不胜感激。 而且，不要忘了通过电子邮件订阅，以获取诸如此类鲜为人知的新特性。

**祝您学习愉快！**