[英]How IIOException has no no-arg constructor?
Suppose we have a class NoArgConstructorClass in a file NoArgConstructorClass.java 假设我们在NoArgConstructorClass.java文件中有一个NoArgConstructorClass类
/* first example */
import javax.imageio.IIOException;
public class NoArgConstructorClass
{
public static void main(String[] args)
{
NoArgConstructorClass n = new NoArgConstructorClass();
IIOException e = new IIOException();
}
}
This code on compilation produces error: no suitable constructor found for IIOException. 编译时产生以下错误:没有为IIOException找到合适的构造函数。
Since IIOException should have a no-arg constructor (added by compilator), how it is made that there is no no-arg constructor for IIOException? 由于IIOException应该具有无参数构造函数(由编译器添加),如何使IIOException没有无参数构造函数?
/** second example, showing that ClassB inherits a no-arg constructor from Object */
/** put in ConstructorChain.java */
public class ConstructorChain
{
public static void main(String[] args)
{
ClassB b = new ClassB();
}
}
/** put in ClassA.java */
public class ClassA
{
public ClassA()
{
System.out.println("Class A");
}
}
/** put in ClassB.java */
public class ClassB
extends ClassA
{
}
Q. This code on compilation produces error: no suitable constructor found for IIOException. 问:编译时此代码产生错误:没有为IIOException找到合适的构造函数。
If you look at the docs of IIOException
, you can see that it does not have a default(no-arg) constructor. 如果查看IIOException
的文档, IIOException
可以看到它没有默认的(无参数)构造函数。 It has 2 constructors and both are parameterized(single parameter and double parameter). 它有2个构造函数,并且都已参数化(单参数和双参数)。 That is why you get the compilation error when you try to create a IIOException
instance with the no-arg constructor. 这就是为什么在尝试使用no-arg构造函数创建IIOException
实例时收到编译错误的原因。
Q. Since IIOException should inherit a no-arg constructor from Object, how it is made that there is no no-arg constructor for IIOException? 问:由于IIOException应该从Object继承无参数构造函数,如何使IIOException没有无参数构造函数?
It doesn't inherit a no-arg constructor. 它不继承无参数构造函数。 When a class is inherited, you either add a call to its super class constructor using super()
or the compiler does that in case you don't do it. 当一个类被继承时,您可以使用super()
向其超类构造函数添加调用,或者在编译器不这样做的情况下进行编译。 So the constructor of the IIOException
would look something like this. 因此, IIOException
的构造IIOException
将如下所示。
public IIOException(String message) {
// if the below line is not present, the compiler adds it
super(); // This calls the parent class (IOException) constructor and since there is a no-arg constructor there, its perfectly valid
... // other code
}
I re-read your question twice now, and I think you are taking the compiler's adding of a default no-arg constructor as an constructor inherited from the parent class. 我现在重新阅读了两次您的问题,我认为您是在将编译器的默认no-arg构造函数添加为从父类继承的构造函数。
As mentioned in the JLS-8.8.9 (thanks to the OP for the link), 如JLS-8.8.9中所述 (感谢链接的OP),
If you have a class without a constructor(with or without arg), the compiler adds a default no-arg constructor by itself. 如果您有一个没有构造函数的类(有或没有arg),则编译器会自行添加默认的无参数构造函数。 BUT if you specify a constructor with arg and do not specify a no-arg constructor, then the compiler DOES NOT add a default no-arg constructor to the class. 但是,如果您指定带有arg的构造函数而未指定no-arg构造函数,则编译器不会向该类添加默认的no-arg构造函数。 Let me cite an example. 让我举一个例子。
class A {}
You can instantiate class A
using A a = new A()
because even if you haven't specified any constructor, a default no-arg constructor is added to the class. 您可以使用A a = new A()
来实例化类A
因为即使您未指定任何构造函数,也会向该类中添加默认的无参数构造函数。
But if your class looks like this, 但是如果你的班级看起来像这样,
class A {
public A(int b) {
}
}
In this case, you have a single argument constructor. 在这种情况下,您只有一个参数构造函数。 You can now instantiate your class only using this constructor as the compiler doesn't add a default no-arg constructor to it as it already has a constructor(with one argument). 现在,您只能使用此构造函数实例化您的类,因为编译器不会向其添加默认的无参数构造函数,因为它已经具有一个构造函数(带有一个参数)。 Therefore, A a = new A(1)
would work whereas A a = new A()
would not. 因此, A a = new A(1)
将起作用,而A a = new A()
将不起作用。
If you want to be able to create a instance like this, A a = new A()
, then you need to explicitly add a no-arg constructor to your class, like this 如果您希望能够创建一个这样的实例A a = new A()
,那么您需要向类中显式添加一个no-arg构造函数。
class A {
public A(int b) { // single argument constructor
}
public A() { // no argument constructor
}
}
If you are using below code instead of example 2 then it will produce compilation error. 如果使用下面的代码而不是示例2,则将产生编译错误。 IIOException is work like this. IIOException是这样的工作。 so you get the compilation error in example 1. 因此您在示例1中遇到编译错误。
public class ConstructorChain
{
public static void main(String[] args)
{
ClassB b = new ClassB();
}
}
class ClassA
{
public ClassA()
{
System.out.println("Class A");
}
}
/** put in ClassB.java */
class ClassB
extends ClassA
{
ClassB(String str)
{
}
}
If a class has no constructors (as in ClassB), then according to Java Language Specification 8.8.9 "Default constructor" : " If a class contains no constructor declarations , then a default constructor with no formal parameters and no throws clause is implicitly declared ." 如果一个类没有构造函数(如在ClassB中),则根据Java语言规范8.8.9“默认构造函数” :“ 如果一个类不包含构造函数声明 , 则 隐式声明 一个没有形式参数且没有throws子句的默认构造函数 ”。
So, if the class has at least one constructor, then it should have it's own declaration of no-arg constructor to have it actually. 因此,如果该类至少具有一个构造函数,则它应该具有自己的no-arg构造函数声明来实际具有它。
So if the ClassB has at least one constructor 因此,如果ClassB具有至少一个构造函数
/** put in ClassB.java */
public class ClassB
extends ClassA
{
public ClassB(String s)
{
}
}
then it will not have a no-arg constructor unless it is defined explicitly: 则除非明确定义,否则它将没有no-arg构造函数:
/** put in ClassB.java */
public class ClassB
extends ClassA
{
public ClassB()
{
}
public ClassB(String s)
{
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.