Hibernate and no-arg constructor - java

As we can read here Hibenate requires no-arg constructor for all the #Entity classes. But isn't it true that java class has always implicit default constuctor, even if we don't declare one explicitly?
In my project I don't declare a no-arg constructor in my #Entity classes and eveything works fine. But on the other hand, I guess that Hibernate specification has been written carefully so maybe actually declaring explicitely default constructor may have some benefits?

If you create other constructor, java will not create implicit constructor.

There are no special benefits of defining the no-arg constructor explicitly for the Entity Classes (But remember that, Hibernate framework internally uses the no-arg constructor to populate entities through Java reflection API).
It is mandatory that the Hibernate Entity Bean Classes require no-arg constructors, which can be defined explicitly by the programmer (or auto. generated by Java).
One important point is that when you are defining your own constructor(s) for the class, you need to provide the no-arg constructor by yourself (because the compiler does not provide in this case).

In Hibernate, no-arg constructor is used to loading database entities via Reflection(that is used to examine or modify application behaviour at runtime).

The implementation of the default no arg constructor, is not mandatory even for Hibernate, because java automatically and implicitely manage it.
And the only case where you need to specify it is when you declare another parametrized constructor.
If you take a look at The No-Arg Constructor, you will see that:
Every class has at least one constructor. There are two cases:
If you do not write a constructor for a class, Java generates one
for
you. This generated constructor is called a default constructor. It's
not visible in your code, but it's there just the same. If you could
see it, it would look like this (for the class Dog):
public Dog() { } Notice that this default constructor takes no arguments and has a body that does nothing.
If you do write a constructor for your class, Java does not generate
a
default constructor. This could be a problem if you have pre-existing
code that uses the default constructor.

If you don't define any constructors, the compiler will generate the default one, as described in the JLS:
If a class contains no constructor declarations, then a default
constructor with no formal parameters and no throws clause is
implicitly declared.
If the class being declared is the primordial class Object, then the
default constructor has an empty body. Otherwise, the default
constructor simply invokes the superclass constructor with no
arguments.
This means that you don't have to explicitly implement the no-arg constructor for a Hibernate entity as long as:
You don't have any other constructors in the entity class;
The extended superclass has a no-arg constructor without a throws clause for any checked exceptions.

Java class might have no implicit default constructor.
Suppose, you have such a class:
public class A {
public A(String st) {}
}
Eventually the only constructor would be A(String st), not A(String st) and A().

Related

How does default constructor used to instantiate object if it's super class no argument constructor has empty body?

default constructor invoke no_argument constructor in super class reference
and this last constructor used to instantiate object from this class,How ? i mean what does superclass constructor body exactly do ?
example
public class Child extend Fragment {}
if i tried to instantiate this class Child
Child a = new Child() ;
while compiling compiler invoke no-argument constructor in Fragment class .
in android.app package i found that no-argument constructor has no body
public Fragment() {}
Question how could this constructor be useful ? it do nothing !
P.S
i mean by
how could this constructor be useful?
how does it instantiate its class although it empty , where is the code that instantiate super class?
Question how could this constructor be useful ? it do nothing !
The purpose of a constructor, whether empty or not, is to provide an instance of the class. The constructor body, if it exists, may further do additional operations necessary when first creating the instance.
The constructor may not be doing anything itself but it returns an instance, on which you may further call public methods defined in the class.
For example, in your mentioned Fragment class, let's suppose there is an attach() method. If the attach() method is non-static, you will need to create an instance (using the empty constructor) to call the attach() method on it irrespective of whether the constructor does anything or not.
how does it instantiate its class although it empty
A constructor doesn't need any code in its body to be instantiated.
Calling new ClassName() (with appropriate parameters, if any) is enough. It is the job of JVM to create the object at runtime. You don't need to write any specific code inside a constructor for that. That extra code, if you wish, can help the instance start off with a specific state by setting some fields or calling methods, etc.
where is the code that instantiate super class?
A constructor in a subclass (or any class, for that matter) only generates an instance of that class. It doesn't need to instantiate its super class. You may call the super class constructor (using super()) if it has some important initialization code, but it's not compulsory. Also, subclasses don't inherit constructors from super classes. But they do inherit the public and protected fields and methods.
Regarding the Fragment class, you have have some confusion regarding its use which can be clarified here.
The syntax for calling a superclass constructor is
super();
or:
super(parameter list);
Question how could this constructor be useful ? it do nothing !
The super constructor could be used to initialized properties common for all subclasses. If it's empty it still can be used by reflection API.
Fragment.class.getConstructor().newInstance();
or
Child a = new Child() ;
a.getClass().getSuperclass().getConstructor().newInstance();
the last line explicitly invokes a constructor of the superclass.
an empty constructor (aka default constructor) means only that an instance can be created without any further work. This can be due to framework requirements or the instantation is ok with the default values for the attributes.
If the empty constructor is the only constructor in the class, it is not required to write it, its there by default.
Although if there are other constructors (with parameters), one must explicitly state the default constructor.

Why did it become a convention to create a non-arg constructor in a javabean?

I know
A JavaBean is just a standard
All properties private (use getters/setters)
A public no-argument constructor
Implements Serializable.
Source
We all know it is not required to provide a non argument constructor in a class, because if we have not specified any constructor in our class java compiler will create a non argument constructor. If so why programmers wanted to create a non argument constructor in a javabean as a convention.
You are confusing requirements on the JavaBean class with the requirements on its source code. No part of the JavaBeans specification deals with how your source code must look like, it is strictly about the resulting class.
So yes, each JavaBeans class must provide a nullary constructor, and how you achieve that with source code (or even with a bytecode generator) is completely up to you.
It is considered good practice by some to always include the non-arg constructor in your code, because that prevents the scenario where a later maintenance introduces another constructor, thereby discarding the implicit non-arg one, thereby breaking any external code that relies on it.
You don't have to create it explicitly. There's no rule saying you have to do that. Even for a JavaBean, it's fine to leave the compiler to create one for you (as long as you're not providing another one, in which case you'd need an explicit no-arg constructor too).
But there does need to be one, explicit or implicit, because the ORM needs to be able to create instances.
You'd want to create a no argument in these cases:
1) You want to do some logic in the no argument constructor, so can't use the default.
2) You have other constructors that take arguments, in that case no default no-arg constructor will be provided for you.
point 2 implies that having an explicit no arg constructor to start with allows you to add future constructors with arguments without worrying about losing the implicit no-arg constructor.
Without one many API internals like ORMs or IOC containers can't instantiate the object in order to proceed with setting the bean properties from the data source or other bean dependencies.
Many do approximately this:
Class<?> clazz = Class.forName("com.foo.BeanClass");
Constructor<?> constructor = clazz.getConstructor();
Object bean = constructor.newInstance();

Is it possible to call the default-constructor instead of the zero-argument constructor?

I have a util class that is supposed to call a method on a given Class object using reflection.
Right now it creates a new instances using .newInstance() and then calls the method I want to test.
The problem is that the zero-arguement constructor of some of my classes throws an Exception due to missing dependencies and such and keeps me from calling the method I actually want to test.
Is it possible to call the default-constructor of Java to create the instance instead of the custom zero-argument constructor?
You only have a default constructor, if the class has no constructors defined.
The no-arg constructor should only take the dependencies you give it (i.e. none) and it appears you believe you can still use the class without additional dependencies.
In Sun/Oracle JVM you can use Unsafe.allocateInstance(Class) which creates an instance without calling a constructor, but I would try to fix your class design first.
A default constructor is only created, when you don't provide a constructor yourself.
So, as soon as your class has at least one constructor, that default constructor isn't being created.

Should we always have a zero-argument constructor in a Class?

Should every Java class have a zero-argument constructor?
No
If it makes no sense to create an instance of the class without supplying any information to the constructor then you need not have a zero-argument constructor.
A good example is java.awt.Color class, whose all ctors are argumented.
No, it doesn't make sense to always create zero argument constructors, the following scenarios are examples where it makes sense to provide at least a-some-argument-constructor
Required dependencies that the class itself cannot create.
There are no senseful defaults for the properties.
Cases where you want to have/need a zero-argument constructor:
You want to comply to the JavaBeans specification (makes sense for simple data objects).
All fields can be initialized using senseful defaults.
You want to use a framework that needs it.
One of the mis-arguments for having a zero-argument constructor in my opinion is a long list of arguments. For that there are better solutions than accepting to initialize an object that isn't in a safe state after creation:
Using the Builder pattern.
Provide specialized container objects to configure an instance via the constructor.
Provide multiple constructors where the base arguments of each one are the required parameters that cannot have defaults assigned.
As Andy Thomas-Cramer has already noted, it is even impossible:
class NeedsToBeImmutable {
// For a class to be immutable, its reachable state
// MUST be reached through a final field
private final String stuff;
//!!Compile error!!
public NeedsToBeImmutable(){}
public NeedsToBeImmutable(String stuff){
this.stuff = stuff;
}
//getters...
}
No. However there are exceptions. For instance, if you intend your class to contain just static util methods or a singleton class or a class with just constants then you should create a private constructor with no arguments to prevent it from being explicitly instantiated.

Why do we need a default no argument constructor in Java?

Why do we need a default no argument constructor in many Java related APIs? Like as a general rule all java bean classes or entity classes (JPA etc) or JAX-WS implementation classes require a explicit no argument constructor.
If by default Java provides a no argument constructor then why most of these standards require a explicit constructor?
Java only provides a default no-argument constructor if no other constructors are defined. Thus, if you have other constructors you must explicitly define a no-arg constructor yourself.
These frameworks use the reflection API and look at method names to determine how to set properties. The arguments of a constructor can only be found by type, not by name, so there is no way for the framework to reliably match properties to constructor args. Therefore, they require a no-arg constructor to create the object, then can use the setter methods to initialise the data.
Some frameworks may support #ConstructorProperties as an alternative.
I believe frameworks that require public nullary constructors do so because they use reflection to instantiate types, e.g. through Class.newInstance().
As to why the default constructor may not work for this case, here's the relevant JLS section:
JLS 8.8.9 Default Constructor
If a class contains no constructor declarations, then a default constructor that takes no parameters is automatically provided:
if the class is declared public, then the default constructor is implicitly given the access modifier public;
if the class is declared protected, then the default constructor is implicitly given the access modifier protected;
if the class is declared private, then the default constructor is implicitly given the access modifier private;
otherwise, the default constructor has the default access implied by no access modifier.
So in a public class, the default constructor would have the right visibility, but otherwise an explicitly public one must be provided.
A constructor is needed to initialise any non-default values and can contain side effects which are needed.
If you have a programing style which encourages a minimal constructor for data transfer objects this would seem unneccasary, but the libraries have chosen not to assume any programming style for the constructors.
You can write a library which doesn't assume a default constructor, but you have to make assumptions about what the constructor would do and wouldn't do. i.e. I have written such libraries but was able to also mandate what a constructor was allowed to do so that not calling it directly was safe.
Java only supplies a no-arg constructor if no other constructor is applied. In a number of Java APIs (e.g. JPA, Serialisation and many others that build objects from an external representation) an instance of the object is required before the data values of the object can be set, as the definition of how the values are applied are defined through instance members of the object (e.g. readExternal(ObjectInput)). If a class only has a constructor that takes some arguments then it may not be possible for the library to construct an instance unless a separate no-arg constructor is defined.
It is worth noting that this is a design choice by the implementer of the particular library, it is possible to build an API/Framework that can externalise and recreate objects that don't have a no-arg constructor (defining a separate factory class is one approach). The pattern of requiring a no-arg constructor turned up first in Java Serialisation (I think) and has been adopted as the de-facto standard approach on other libraries (e.g. JPA). The weakness of this approach is that it prevents the use of immutable objects.
Two reasons:
1) to avoid NullPointerException if an instance data field of a reference data type is uninitialized. Providing an explicit constructor would give you the chance to initialize such data fields, if they have not been initialized when declared
2) for users who would like to use no-arg constructors; these are not automatically provided if other constructors exist
Many of these frameworks derive from the earlier ideas of "POJO" and especially JavaBeans. The smallest useful Java Object would, by convention, have a no-arg constructor and every member accessible through methods like get/setProperty1 and is/setProperty1 for booleans. If Classes follow that convention of the interface, tools and frameworks using reflection can work 'out of the box'.
Default No-Argument constructor provides default values to the object like 0 or null, hence it is mandatory in java coding.

Categories