in other words, can someone explain to me the purpose of this:
Consumer(Producer p) {
producer = p;
}
in the context of:
class Consumer extends Thread {
Producer producer;
Consumer(Producer p) {
producer = p;
}
}
as I understand, it appears to be a method with no signature, or a constructor since it shares the class name, yet it doesn't show up in my IDE as such. Can someone explain what it is and what it does?
Any help would be hugely appreciated.
You are looking at a constructor of class Consumer. The only problem I can see is it is not given a access level (public, private, etc...), so it looks like it will default to package-protected, meaning only classes within the same package can see it.
Consumer(Producer p) { ... } is a constructor for the Consumer class.
You typically see constructors as public, e.g.:
public Consumer(Producer p) { ... }
However, when the public (or any access modifier, e.g. protected, or private) is not specified (for any method or member, including constructors), the constructor is only available to the package the class is declared in.
Have a look at Oracle's tutorial on access control.
Yes, that's a constructor. It may look like a "method with no signature" syntactically (more specifically, a constructor cannot have a return type, but may have access modifiers and of course parameters), but it's really quite different from a method in several ways.
The purpose of a constructor is to create instances (objects) of the class. With some relatively exotic exceptions (cloning and deserialization), every Java object is created by calling a constructor. Every class has at least one constructor, but if none is declared an the superclass has a constructor with no parameters, the compiler implicitly adds a parameterless constructor that does nothing except call the superclass constuctor. Similarly, the first thing any constructor does is call a superclass constructor. Again, this can be implicit if there is a parameterless constructor in the superclass.
As for why constructors don't show up in your ide: it's probably a configuration option. To say more, we'd have to know which IDE that is.
As already mentioned, that is a package protected constructor, i.e. it can only be called from methods of the class itself or other classes in the same package. I'm not sure what benefit that has over the more commonly used protected or private constructors, which prevent a class from being directly instantiated and are commonly used to implement the Singleton pattern.
Related
There are different questions already available related to this error, but none is realted to this specific class i.e BaseEncoding
When i am extending BaseEncoding on my class, I am getting this error,
The constructor BaseEncoding() is not visible
here is the code,
import com.google.common.io.BaseEncoding;
public class TheRace extends BaseEncoding{
public TheRace() {
super();
}
}
from this answer, Constructor not visible
I understand that BaseEncoding() constructor must be expecting some parameters, but when I visit its official documentation, there is no constructor defined.
How can I pass the parameters to solve my issue when there is no parametrized constructor in the BaseEncoding class ?
BaseEncoding isn't meant to be subclassed; its constructor is deliberately made private and not visible outside the class. You're supposed to acquire instances of it using its factory methods like base16().
BaseEncoding is an abstract class. It cannot be instantiated! Therefore defining a constructor isn't necessary (Although possible).
In order to acquire (static) objects of type BaseEncoding, the class does define some factory methods (e.g., BaseEncoding.base16()).
Why are methods on interfaces always public? Why can't they be private?
Because all methods on an interface are public. That's the point in having the interface -- technically it defines a contract for your class (which may have many, overlapping, contracts/interfaces). The client of your class should hold a reference to the interface and have access only to the class' published (public) methods through the interface.
I infer that you are referring to an interface declared thusly:
public interface MyInter
{
public void myFunc();
}
And the resulting error if you omit the public qualifier in your implementation:
MyClass.java:3: myFunc() in MyClass cannot implement myFunc() in MyInter; attempting to assign weaker access privileges; was public
void myFunc(){}
^
Say you could make myFunc private. You write the following code in a different class. This should complain about you trying to use a private function you didn't have access to:
MyClass foo = new MyClass();
foo.myFunc(); // Declared private, can't call it.
But what about this:
void doSomething(MyInter foo)
{
foo.myFunc(); // Declared public in interface, private in implementation.
}
Can we do this? According to the interface it's a public method so we should be good to go. But it's implemented as a private method so the class expects it never to be called from the outside like this, a restriction that should be enforced by the compiler. But the compiler doesn't even need to know about MyClass for this to compile. It could not even be written yet, or in an external library that may or may not ever be integrated.
Allowing implementations creates an internal inconsistency in the rules of allowable access, and the resolution to that inconsistency is to disallow the situation altogether. Anything that can call a method in an interface must be able to call it in any implementation.
The same argument holds true for overriding subclass methods. You can't "hide" them by overriding with more restrictive qualifiers.
Why is it so?
Because the JLS says so:
In the Chapter on interface declarations, JLS 9.4 says: "Every method declaration in the body of an interface is implicitly public."
In the Chapter on class declarations, JLS 8.4.8.3 says: "The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, ..."
Engineer Dollery's answer explains why the language is designed this way.
Why can't constructors be final, static, or abstract in Java?
For instance, can you explain to me why this is not valid?
public class K {
abstract public K() {
// ...
}
}
When you set a method as final it means: "I don't want any class override it." But according to the Java Language Specification:
JLS 8.8 - "Constructor declarations are not members. They are never inherited and therefore are not subject to hiding or overriding."
When you set a method as abstract it means: "This method doesn't have a body and it should be implemented in a child class." But the constructor is called implicitly when the new keyword is used so it can't lack a body.
When you set a method as static it means: "This method belongs to the class, not a particular object." But the constructor is implicitly called to initialize an object, so there is no purpose in having a static constructor.
The question really is why you want constructor to be static or abstract or final.
Constructors aren't inherited so can't be overridden so whats the use
to have final constructor
Constructor is called automatically when an instance of the class is
created, it has access to instance fields of the class. What will be
the use of a static constructor.
Constructor can't be overridden so what will you do with an abstract
constructor.
A Java constructor is implicitly final, the static / non-static aspects of its semantics are implicit1, and it is meaningless for a Java constructor to be abstract.
This means that the final and static modifiers would be redundant, and the abstract keyword would have no meaning at all.
Naturally, the Java designers didn't see in any point in allowing redundant and/or meaningless access modifiers on constructors ... so these are not allowed by the Java grammar.
Aside: It is a shame that they didn't make the same design call for interface methods where the public and abstract modifiers are also redundant, but allowed anyway. Perhaps there is some (ancient) historical reason for this. But either way, it cannot be fixed without rendering (probably) millions of existing Java programs uncompilable.
1 - Actually, constructors have a mixture of static and non-static semantics. You can't "call" a constructor on an instance, and it they are not inherited, or overridable. This is similar to the way static methods work. On the other hand, the body of a constructor can refer to this, and call instance methods ... like an instance method. And then there is constructor chaining, which is unique to constructors. But the real point is that these semantics are fixed, and there is no point allowing a redundant and probably confusing static modifier.
public constructor: Objects can be created anywhere.
default constructor: Objects can be created only in the same package.
protected constructor: Objects can be created by classes outside the package only if it's a subclass.
private constructor: Object can only be created inside the class (e.g., when implementing a singleton).
The static, final and abstract keywords are not meaningful for a constructor because:
static members belong to a class, but the constructor is needed to create an object.
An abstract class is a partially implemented class, which contains abstract methods to be implemented in child class.
final restricts modification: variables become constant, methods can't be overridden, and classes can't be inherited.
Final: Because you can't overwrite/extend a constructor anyway. You can extend a class (to prevent that you make it final) or overwrite a method (to prevent that you make it final), but there is nothing like this for constructors.
Static: If you look at the execution a constructor is not static (it can access instance fields), if you look at the caller side it is (kind of) static (you call it without having an instance. Its hard to imagine a constructor being completely static or not static and without having a semantic separation between those two things it doesn't make sense to distinguish them with a modifier.
Abstract: Abstract makes only sense in the presence of overwriting/extension, so the same argument as for 'final' applies
No Constructors can NEVER be declared as final. Your compiler will always give an error of the type "modifier final not allowed"
Final, when applied to methods, means that the method cannot be overridden in a subclass.
Constructors are NOT ordinary methods. (different rules apply)
Additionally, Constructors are NEVER inherited. So there is NO SENSE in declaring it final.
Constructors are NOT ordinary methods. (different rules apply)
Additionally, Constructors are NEVER inherited. So there is NO SENSE in declaring it final.
No Constructors can NEVER be declared final. YOur compiler will always give an error of the type "modifer final not allowed"
Check the JLS Section 8.8.3 (The JLS & API docs should be some of your primary sources of information).
JLS section 8 mentions this.
Constructors (§8.8) are similar to methods, but cannot be invoked
directly by a method call; they are used to initialize new class
instances. Like methods, they may be overloaded (§8.8.8).
But constructors per say are not regular methods. They can't be compared as such.
why constructor can not be static and final are well defined in above answers.
Abstract: "Abstract" means no implementation . and it can only be implemented via inheritance. So when we extends some class, all of parent class members are inherited in sub-class(child class) except "Constructor". So, lets suppose, you some how manage to declare constructor "Abstract", than how can you give its implementation in sub class, when constructor does not get inherit in child-class?
that's why constructor can't be
abstract .
lets see first
final public K(){
*above the modifier final is restrict 'cause if it final then some situation where in some other class or same class only we will override it so thats not gonna happen here proximately not final
eg:
we want public void(int i,String name){
//this code not allowed
let static,, static itz all about class level but we create the object based constructor by using 'new' keyword so,,,,,, thatsall
abstract itz worst about here not at 'cause not have any abstract method or any declared method
Unfortunately in PHP the compiler does not raise any issue for both abstract and final constructor.
<?php
abstract class AbstractClass
{
public abstract function __construct();
}
class NormalClass
{
public final function __construct() {
echo "Final constructor in a normal class!";
}
}
In PHP static constructor is not allowed and will raise fatal exception.
Here in AbstractClass obviously a constructor either can be declared as abstract plus not implemented or it can be declared as something among (final, public, private, protected) plus a function body.
Some other related facts on PHP:
In PHP having multiple constructor __construct() is not possible.
In PHP a constructor __construct() can be declared as abstract, final, public, private and protected!
This code was tested and stood true for in PHP versions from 5.6 up to 7.4!
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.
I was reading some Java recently and came across something (an idiom?) new to me: in the program, classes with multiple constructors would also always include a blank constructor. For example:
public class Genotype {
private boolean bits[];
private int rating;
private int length;
private Random random;
public Genotype() { // <= THIS is the bandit, this one right here
random = new Random();
}
/* creates a Random genetoype */
public Genotype(int length, Random r) {
random = r;
this.length = length;
bits = new boolean[length];
for(int i=0;i<length;i++) {
bits[i] =random.nextBoolean();
}
}
/* copy constructor */
public Genotype(Genotype g,Random r) {
random = r;
bits = new boolean[g.length];
rating = g.rating;
length = g.length;
for(int i=0;i<length;i++) {
bits[i] = g.bits[i];
}
}
}
The first constructor doesn't seem to be a "real" constructor, it seems as though in every case one of the other constructors will be used. So why is that constructor defined at all?
I am not sure that the code you were reading was high quality (I've reviewed some bioinformatics code in the past and it is unfortunately often not written by professional developers). For example, that third constructor is not a copy constructor and generally there are problems in this code, so I wouldn't "read too much into it".
The first constructor is a default constructor. It only initializes the bare minimum and lets users set the rest with getters and setters. Other constructors are often "convenience constructors" that help create objects with less calls. However, this can often lead to inconsistencies between constructors. In fact, there is recent research that shows that a default constructor with subsequent calls to setters is preferable.
There are also certain cases where a default constructor is critical. For example, certain frameworks like digester (used to create objects directly from XML) use default constructors. JavaBeans in general use default constructors, etc.
Also, some classes inherit from other classes. you may see a default constructor when the initialization of the parent object is "good enough".
In this specific case, if that constructor was not defined, one would have to know all the details in advance. That is not always preferable.
And finally, some IDEs automatically generate a default constructor, it is possible that whoever wrote the class was afraid to eliminate it.
Is the object Serializable?
To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream
Yes, I agree the "blank" constructor should not always exist (in my experience beginners often make this mistake), although there are cases when blank constructor would suffice. However if the blank constructor violates the invariant that all the members are properly instantiated after construction, blank constructor should not be used. If the constructor is complicated, it is better to divide the construction into several protected/private methods. Then use a static method or another Factory class to call the protected methods for construction, as needed.
What I wrote above is the ideal scenario. However, frameworks like spring remove the constructor logic out of the code and into some xml configuration files. You may have getter and setter functions, but probably may be avoided from the interface, as described here.
Default constructor is NOT mandatory.
If no constructors defined in the class then default (empty) constructor will be created automatically. If you've provided any parametrized constructor(s) then default constructor will not be created automatically and it's better to create it by yourself. Frameworks that use dependency injection and dynamic proxy creation at runtime usually require default constructor. So, it depends on use cases of class that you write.
The default constructor is'nt a good pratice for the functional view.
The default constructor is used if the object have a global visibility into a method: for example, you want log the actual state of a object in a try/catch
you can code
MyObejct myObject=null
try{...
}catch(Exception e){
log.error(myObject);//maybe print null. information?
}
or do you prefer
MyObejct myObject=new Object();
try{...
}catch(Exception e){
log.error(myObject);//sure print myobject.toString, never null. More information
}
?
Anotherway the create a EMPTY object have'nt a lot of logic, but instatiate a NULL object is harmuful in my opinion.
You can read this post
That is NOT a copy constructor. Basically you want empty constructors when working with some framework. Shall there always be an empty constructor, of course, public or private, but at least it allows you to keep control of how the class is being (or not) instantiated.
I usually write one constructor that fully initializes the object; if there are others, they all call this(...) with appropriate defaults.
An object should be 100% initialized and ready for use when it's created.
Some frameworks, for example Hibernate, demand a no-arg constructor. The way they clash with best practices makes me uneasy sometimes.
Having a default and empty (blank) constructor prevents you from having any final fields. This leads to a lot of mutability where there it is often not needed.
The builder pattern allows you to mix these two styles and allow more flexible initialization while still having immutability by hiding a many-arg constructor behind the factory.
For some POJO classes or simple class, default constructor is useful when you sometimes want to do unit testing on the class using them. You don't need to mock them, you can new an object with default constructor and test the value set and get from them or pass them as an argument.
You want to create a blank constructor for the classes that extended this
class and since it has been extended the class... the child now has super which references the class above it it's parent. In the event the child did not specify super(stuff)... the stuff inside to reference the other constructors to use it will now attempt to reference the empty constructor.
I'm not sure what the error will be I am coding my first parent object relationship now and was looking up things here ha cheers.
I guess I should add the moment you make a constructor that isn't the empty one you lose the default empty one so now super() which is default in the extended class won't have something to point to. Of course if you created the extended classes to take care of super by specifying on which gets rid of the default super() then you sidestep this but what if someone wants to use your class and extend from it and didn't realize there isn't an empty set when you could have
just created one.
This is my first post but wanted to take a crack from how I understand it.