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

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

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

这篇文章是对 Java 鲜为人知的特性的继续。 在上一篇文章中,我介绍了“相同类的实例可以访问彼此的私有成员”,以及一些非常令人惊讶的sun.misc.Unsafe类的用法。 在本文中,我将讨论一个关于初始化块的鲜为人知的特性。

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

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

1)非静态初始化器块

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

2)静态初始化器块

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

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

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

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

上面的代码引发了两个受检的异常IOExceptionJDOMException。您可以使用try-catch处理它们。 例如:

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

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

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

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

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

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/>")));
	}
}

或者:

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;
		}
	}
}

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

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

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

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
		}
	}
}

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

祝您学习愉快!