简体   繁体   English

IIOException如何没有no-arg构造函数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM