Cannot find constructor File() in java.io.File - java

This is probably obvious, so bear with me.
YES, I KNOW THAT java.io.File has no default constructor.
The problem is that When I try to extend java.io.File, it says "Cannot find constructor File() in java.io.File" even though I am overriding the default constructor in java.lang.Object.
Here is my code:
AbsRelFile.java
import java.io.File;
public class AbsRelFile extends File {
File f;
private AbsRelFile(){
}
}
This gives me an error, even though I am overriding the constructor.
NOTE: This class is not finished. Don't make a comment about why wouldn't I need this or a comment about how this class is useless. I just started writing it before I got this Error.

Because you didn't make an explicit call to super(...) in your default constructor, it is implicitly attempting to call the default constructor for the super class, which, as you point out, doesn't exist in this case (the case of super being a File). The solution to your problem is to make a call to the super constructor in your default AbsRelFile() constructor. If you wan't to provide a default constructor for your class, you're going to need to call super(...) with some default values.

When you define a constructor, Java inserts an implicit call to the super constructor as the very first line of the constructor. So your constructor is equivalent to:
private AbsRelFile(){
super();
}
Since there is no default constructor in the super class File, it gives an error. To fix this, you need to place an explicit call to the super class constructor as the first line:
private AbsRelFile(){
super("fileName");
}
Most probably, you'll have to define some suitable parameters for AbsRelFile constructor too which you can pass to super call.
On another note, constructors cannot be overridden. So it is wrong to say that you're overriding the Object class constructor. You're simply defining a constrcutor for AbsRelFile class.

Constructors, by default, call the default constructor of the super-class if you don't make a super constructor call yourself.
To avoid this, make a call to an actually-defined constructor of File.

Java automatically puts in a call to super() in your empty constructor, which is why you get the error.

The problem is that your AbsRelFile constructor is trying to call the no-args constructor of File. What you have written is equivalent to
private AbsRelFile() {
super();
}
You need to make sure that you explicitly invoke one of the File constructors that does exist. For example:
private AbsRelFile() {
super("dummy");
}
Obviously, you will need to figure out a safe / harmless / appropriate superclass constructor and arguments to use for your particular use-case. (I haven't a clue what an AbsRefFile is really supposed to be ... so I cannot advise on that.)
Aside - you don't "override" constructors. Constructors are never inherited in Java, so overriding simply doesn't apply here. Instead you declare constructors in the subclass, and have them chain to the appropriate constructors in the immediate superclass via an explicit super(...) call ... or the implicit one the Java inserts by default.

First of all, I hope your field "File f" is not related to trying to access the superclass, but something to do with 'Rel' or 'Abs'..
The other posters have correctly pointed out that your implicit default constructor (AbsRelfile()) will attempt to call super() - which does not exist. So the only solution is to make a constructor that passes down some valid arguments.
If you are attempting to 'wrap' the whole java.util.File class (like when making your own Exception) you should probably provide a wrapper for each of the original constructors. Modern IDEs like Eclipse should have this a right-click away.
Note that File does not require that the given filename exists, in particular it does not exist when you want to do operations like file.mkdir().
If you need an actual, temporary file to work with, you could always do something like:
public class AbsRelFile() {
public AbsRelFile() {
super(File.createTempFile("AbsRelFile", "tmp").getAbsolutePath());
}
}
.. but I'm puzzled as to why you want to subclass File in the first place.

To explain WHY in one line:
When you define a constructor with a parameter (as in the File class), Java compiler WILL NOT generate the default constructor for you.

Related

Why does eclipse automatically add a java super() method in a constructor when I use the editors code generator?

When I write a constructor in my java class, I typically do not invoke super() in there. When I generate the constructor from eclipse source code editor, why does it always add the super() in there?
Am I wrong for not adding this by default in the constructors I write? Any thing wrong with leaving the super() call in the constructor if I decide to use eclipse code generator?
As #Kon correctly points out, there is an implicit call to the default super constructor anyway (this can be easily verified by checking the bytecode with javap -c). If you don't want Eclipse to make it explicit, simply check the "Omit call to default constructor super()" checkbox at the bottom of the constructor creation GUI.
Am I wrong for not adding this by default in the constructors I write?
No, as long as long as you're referring to the default super constructor call super(). If the super constructor takes parameters, for example, then you need to make the call explicit.
Any thing wrong with leaving the super() call in the constructor if I decide to use eclipse code generator?
No, not at all.
As #Kon mentioned in his comment, an empty constructor in Java contains an implicit call to the superclass constructor.
Moreover, a non-empty constructor without an explicit call to super() will have an implicit call at the top.
The only time when it is wrong to leave the super() call there is if you intend to call a different superclass constructor yourself, with parameters.
See this question for more details.
Update: Consider the following code, which illustrates the scenario where it is wrong to leave the super() generated by eclipse.
public class Foo{
public Foo(int a, int b) {
System.out.println("Foo constructor with-args is called");
}
public Foo() {
System.out.println("Foo with no-args is called");
}
}
class Bar extends Foo {
public Bar() {
// Implicit call to super()
super();
// Explicit call to super(a,b);
// This will not compile unless the call above has been removed.
super(1,2);
}
}
Nothing wrong it's just a coding style preference. Some people like to write code that is implicit and some don't.
If you don't call super constructor from your child class constructor compiler will place call to super's default constructor in byte code for you.
See this SO question as well

Why Default constructor need to declare in POJO file which has Parameterized Constructor while instantiating Object?

Suppose I have one POJO class User with a constuctor public User(int id, String name){...}.
But when I instantiate the User object like User u=new User() with no parameter Eclipse gives error like The constructor User() is undefined. But it works fine when I have no parameterized Constructor. Can someone please explain why It requires to define default constructor?
The default (no-parameter) constructor is ONLY provided if you have provided no others. If you define even a single constructor for your class, you MUST use one of the explicitly defined (ie, in your code) constructors to instantiate the object. You can, of course, define your own zero-parameter, empty constructor if that works for what you're trying to do.
Edit:
Answer of why?
The compiler provides a default constructor so that the Object can be Instantiated when there are no constructors defined. But if you have defined a parametric constructor, it means that when you create a new instance of that class, its variables should initialized with the parameters you have passed(or do something similar). Without those initializations, the object might not behave in an expected way. Hence the compiler prevents such things from happening by not defining a default constructor(when you have defined one).
The no-arg constructor will be automatically added by the compiler if no constructor is provided by the developer. However, as soon as you put your own custom parameterized constructor, the compiler stops adding default constructor for you.
In this scenario, if you still want to use your no-arg constructor, you have to provide it yourself explicitly:
public User() {
}
public User(int id, String name) {
}
The logic behind this is that: if you define your own parametrized constructor, you are declaring that the parameters listed in the constructor is required to construct an object of the class. Therefore you are also implicitly declares if the user of your library do not provide these two parameters, the object shouldn't be able to construct. Thus the compiler will not add the no-arg constructor for you.
If you want to also declare that your class can still work if none of the specified parameters in the parametrized constructor is provided and you (no arg), then you have the explicitly declare that by providing the non-arg constructor yourself.
I am giving answer so late, but let's try to share with you what i know:
When you don't provide constructor compiler provides constructor. Why ? Because it is sure you are going to initialize your object with no argument constructor only. So compiler does it for you.
When you provide parameterised constructor, then compiler doesn't know which constructor you will use to initialize your object. So compiler does not provide for you one no-argument constructor. So you have to write explicitly.
Hope it will help you.
The compiler automatically provides a no-argument, default constructor for any class without constructors but if you explicitly provide any constructor with arguments then compiler will not provide a default constructor mainly due to security reasons.
So what you can do is
public User(int id, String name){...}
public User(){this(defualtID,defaultName)};
Java compiler automatically provides a no-parameter, default constructor for any class without constructors. If there is no constructor defined in your class then Java compiler will add a no parameter constructor in your generated class file. But if there is a constructor with parameter in your class, then you need to write the no-parameter constructor, compiler will not add it.

Calling superclass constructor with super or just setTitle?

What is the recommended method of setting the title with setTitle("Title")or super("Title") while extending javax.swing.JFrame in terms of performance?
If you grepcode JFrame (in OpenJDK 6-b14), and dig a bit, you see that the constructor JFrame() calls the constructor Frame(), which calls Frame("") (link).
So, since an implicit super() is added if you don't specify a call to any super constructor yourself, it would be (although very slightly so) more effective to call super("Title").
If you're in your constructor, try to delegate as much functionality as possible to the super constructor. It's possible that you can save it from doing some work.
For instance, the default super constructor might create some inner objects that will just get overwritten when you call the setter. If you pass the correct data immediately, you give it the opportunity to be more efficient.
But I think in this specific case, it does not matter much.
It is a good practice to always call the corresponding super(.....) when you extend a class.
As you never know what magic the super constructor does behind the scene.
You never need just
call super();
That's what will be there if you don't specify anything else. You only need to specify the constructor to call if:
You want to call a superclass constructor which has parameters
You want to chain to another constructor in the same class instead of the superclass constructor

What is Implicit constructors on Java

Is it mandatory to call base class constructor in Java?
In C++ it was optional, so I am asking this.
When I extend ArrayAdapter, I get this error: "Implicit super constructor ArrayAdapter<String>() is undefined. Must explicitly invoke another constructor"
So, what is the purpose of calling base constructor? When I create object base class constructor will call & then it comes to derived right.
The no-args constructor is called implicitly if you don't call one yourself, which is invalid if that constructor doesn't exist. The reason it is required to call a super constructor is that the superclass usually has some state it expects to be in after being constructed, which may include private variables that can't be set in a sub-class. If you don't call the constructor, it would leave the object in a probably invalid state, which can cause all kinds of problems.
It's not necessary to call the no-args constructor of super class. If you want to call a constructor with args, user super keyword like show below:
super(arg1, ...);

Class inheritance problem in Java, constructors with and without params

I'm learning Java (2nd year IT student) and I'm having a little problem. With inheritance to be precise. Here's the code:
class Bazowa
{
public Bazowa(int i)
{
System.out.println("konstruktor bazowy 1");
}
public Bazowa(int j, int k)
{
System.out.println("konstruktor bazowy 2");
}
}
class Pochodna extends Bazowa
{
/* Pochodna()
{
System.out.println("konstruktor pochodny bez parametru");
} */
Pochodna(int i)
{
super(i);
System.out.println("konstruktor pochodny z parametrem");
}
}
So, the Pochodna class extends the Bazowa class, and my exercise is to make a superclass that has only constructors with parameters and a subclass that has both types (with and without).
When I comment the first constructor in Pochodna class, everything works fine, but I don't really know how to make it work without commenting that part. I guess that I have to somehow call the constructor from the first one, but don't have an idea how to do that.
Any help would be appreciated,
Paul
Your first constructor from Pochodna calls by default super(), a constructor which you do not have in Bazowa.
You should either call one of the base constructors with 1 or 2 params in Pochodna(), or create a constructor with no parameters in your base class.
EDIT: Since you said you are learning Java, I will add some extra explanations to my answer.
Every class must have a constructor, so when you do not declare one explicitly, the compiler does so for you, creating a default constructor with no parameters. This constructor won’t be added if YOU declare constructors explicitly.
In inheritance, the child class is a “specialization” of the parent. That means that the child class contains the attributes and behavior of the parent class and extends on them. But you do not declare the parent elements again (unless you really want to overwrite stuff). So, when you create an instance of the child, somehow the elements taken from the parent must also be initialized. For this you have the super(...) construct.
The first thing that must be in a child constructor is a call to super(...) so that the elements taken from the parent are properly initialized before the child tries to do something with them (you can also have a call to another of child’s constructor this(...) – in this case, the last child constructor in the calling chain will call super(...) ).
Because of this, the compiler will again add a default call to super() – with no parameters – for you when you do not do so yourself in the child.
In the first constructor of Pochodna, since you did not call super(i) or super(j, k) yourself, a call to super() was placed by default. But in the parent class you explicitly specified constructors, so the default was not created by the compiler. And from here the exception, you end up calling a constructor that does not exist.
Hope this makes it easier to learn Inheritance. Cheers.
You need to specify something like this:
Pochodna()
{
super(0);
}
The trick here is that since you specify a constructor for the superclass the compiler doesn't create a no-arg constructor for you. When you make your zero-arg constructor in the superclass it tries to call the no-arg constructor in the subclass and fails to find anything.
In short, calling another constructor (either in the superclass or in the same class) in your constructor is not optional. Either you specify another constructor explicitly or a call to the superclass' zero-arg constructor will get inserted.
Since the base class does not have a parameterless constructor, you will need to call a constructor explicitly using super, providing some kind of a default value.
For example:
Pochodna()
{
super(0);
System.out.println("konstruktor pochodny bez parametru");
}
Alternatively, you can create a protected parameterless constructor in the base class. It will not be directly accessible from the outside, but derived classes will be able to use it.
Other answers handle the call to the super constructor.
Note that you could also do this:
Pochodna() {
this(0);
System.out.println("konstruktor pochodny bez parametru");
}
which would call your other constructor for Pochodna. Just another option. Study the output to understand what is happening.
As the default constructor is not present in the parent, you have to call the other constructor in the child constructor:
Pochodna() {
super(10);
}

Categories

Resources