private field vs private static field in abstract class - java

I am confused about the scope of a private field versus a private static field of an abstract class. For example, consider the following classes and note the field validator,
abstract class ValidComponent {
private static Validator validator = ... //(statement to instantiate new Validator)
/**
* This method is to be used by subclasses in their factory-methods
* to do some validation logic after instantiation.
*/
protected void selfValidate() {
//validation logic
...
validator.validate(this); // <<< This line uses the validator
...
}
}
class ValidUsername extends ValidComponent {
private #NotEmpty String core;
private ValidUsername(String unamestr) {
this.core = unamestr;
}
/** This is the factory-method who use selfValidate() */
public static ValidUsername create(String unamestr) {
ValidUsername vuname = new ValidUsername(unamestr);
vuname.selfValidate();
return vuname;
}
}
class ValidEmail extends ValidComponent {
private #Email String core;
private ValidEmail(String emailstr) {
this.core = emailstr;
}
/** This is the factory-method who use selfValidate() */
public static ValidEmail create(String emailstr) {
ValidEmail vemail = new ValidEmail(emailstr);
vemail.selfValidate();
return vemail;
}
}
The abstract class ValidComponent prepares method selfValidate(), in which the private static field, validator, is used.
The ValidUsername and ValidEmail are subclasses that illustrate the intention of their base class: the method selfValidate() are used in their factory-methods to validate themself.
If my understanding is correct, when vuname.selfValidate() and vemail.selfValidate() are called, both use the same Validator object, i.e. ValidComponent.validator.
But what if I happen to change the modifiers of validator from private static to only private, are Validor objects used in vuname.selfValidate() and vemail.selfValidate() still the same object?

No they are not. The static keyword means the field belongs to a class. It will be a single instance across whole VM. Without the static keyword the field belongs to an object, so each instance of the ValidComponent or its subclasses will produce new Validator object.

I'm not sure but I don't think this is appropriate, to use the same Validator for different objects. Your Valid* classes don't share the same constraints therefore the same validation errors. Sharing the same object can cause inconsistency.
You can change private static to private, but your design might be problematic from the outset.
Maybe factory pattern suits you better.
To answer your question
are still the same object?
No they are not.

are Validor objects used in vuname.selfValidate() and
vemail.selfValidate() still the same object?
No, only static data member can be shared whether private or not. Here private static Validator validator = ...is a data member of class ValidComponent whereas private Validator validator = ...is a data member of object and can't share with another object.

Consider a private variable,
private String name;
and its getter/setter which are ofcourse public.
Now every class has access to getter/setter which in its implementation uses private variable. That's the purpose of private variables, not accessing it directly from other classes.
Your case is similar where in private validator is being accessed by selfValidate() method. By their signature, selfValidate() is accessible to subclasses.
To answer your question about whether validator object will be different in case of non-static or not, then every class that accesses it will create a new instance of that object.

Related

Static Factory Method

I learned that static methods are used to create an instance of a class type. I see that some classes using static method have to declare a private constructor for that class.
What is the use of private constructor? Can we still create an instance of a class without using the private constructor? Thanks.
Basically we use this kind of static factory method in Singleton Design Pattern.
Singleton means based on this design pattern we can create only one object for the class.
for Example:
class Test{
private static Test mObject;
private Test()
{
}
public static Test getInstance(){
if(mObject==null){
mObject=new Test();
}
return mObject;
}
}
What is the use of Private Constructor?
If a class has only private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class
Can we still create an instance of a class without using Private
Constructor
Yes using reflection (need to call setAccessible of constructor)

Use of a private constructor

I'm a begginer programmer for Android and I found some code over the internet and I couldn't get what this "Class not meant to be instantiated" means?! Also what's the use of it. I would be very happy if somebody could help here.
public class Settings
{
//some code
private Settings() {} // Class not meant to be instantiated
//some code
}
The constructor is private so only the class itself can create instances. There are several reasons for doing this. A couple off the top of my head...
The class is a "utility" class that only contains static methods and so instantiating it would make no sense. As the class is commented "Class not meant to be instantiated" I guess this is the most likely reason.
The class itself controls its own lifecycle and provides methods for creating instances. For example if the class is a lazy singleton it might provide a method that creates an instance when first called and return this instance on subsequent calls.
It is a private constructor. This means that outside classes cannot create new instances using the default constructor.
A little more info
All Objects in Java have a default constructor:
public MyObject() {}
That is how you can have this class:
public class MyObject{}
and still be able to call:
MyObject mObj = new MyObject();
Private Constructors
Sometimes a developer may not want this default constructor to be visible. Adding any other constructor will nullify this constructor. This can either be a declared constructor with empty parameters (with any of the visibility modifiers) or it can be a different constructor all together.
In the case above, it is likely that one of the following models is followed:
The Settings object is instantiated within the Settings class, and is where all the code is run (a common model for Java - where such a class would also contain a static main(String[] args) method).
The Settings object has other, public constructors.
The Settings object is a Singleton, whereby one static instance of the Settings Object is provided to Objects through an accessor method. For example:
public class MyObject {
private static MyObject instance;
private MyObject(){}//overrides the default constructor
public static MyObject sharedMyObject() {
if (instance == null)
instance = new MyObject();//calls the private constructor
return instance;
}
}
This inner construct
private Settings() {}
is a constructor for Settings instances. Since it is private, nobody can access it (outside of the class itself) and therefore no instances can be created.
The constructor is private so its not meant to be called by anything outside of the class
It's not a nested class, it's a constructor. A private constructor means that you can't construct instances of this class from outside, like this:
Settings s = new Settings(); //Compilation error! :(
Now, if a class can't be instantiated, what could it be for? The most likely reason for this is that the class would return instances of itself from a static method, probably as a singleton. The settings are normally global to the program, so a singleton pattern really fits here. So there would be a static method that goes kind of like this
static private TheOnlySettings = null;
static public getSettings()
{
if(TheOnlySettings == null)
TheOnlySettings = new Settings(); //Legal, since it's inside the Settings class
return TheOnlySettings;
}
See if that's indeed the case.
As other have mentioned, a class having private constructors cannot be instantiated from outside the class. A static method can be used in this case.
class Demo
{
private Demo()
{
}
static void createObjects()
{
Demo o = new Demo();
}
}
class Test
{
public static void main (String ...ar)
{
Demo.createObjects();
}
}
We can have private constructor . Below program depicts the use of private constructor with a static function
class PrivateConstructor {
private:
PrivateConstructor(){
cout << "constructor called" << endl;
}
public:
static void display() {
PrivateConstructor();
}
};
int main() {
PrivateConstructor::display();
}

How to disable warning on Sonar: Hide Utility Class Constructor?

I'm getting this warning on Sonar:
Hide Utility Class Constructor:
Utility classes should not have a public or default constructor
My class:
public class FilePathHelper {
private static String resourcesPath;
public static String getFilePath(HttpServletRequest request) {
if(resourcesPath == null) {
String serverpath = request.getSession()
.getServletContext()
.getRealPath("");
resourcesPath = serverpath + "/WEB-INF/classes/";
}
return resourcesPath;
}
}
I want solution to remove this warning on Sonar Qube.
If this class is only a utility class, you should make the class final and define a private constructor:
public final class FilePathHelper {
private FilePathHelper() {
//not called
}
}
This prevents the default parameter-less constructor from being used elsewhere in your code.
Additionally, you can make the class final, so that it can't be extended in subclasses, which is a best practice for utility classes. Since you declared only a private constructor, other classes wouldn't be able to extend it anyway, but it is still a best practice to mark the class as final.
I don't know Sonar, but I suspect it's looking for a private constructor:
private FilePathHelper() {
// No-op; won't be called
}
Otherwise the Java compiler will provide a public parameterless constructor, which you really don't want.
(You should also make the class final, although other classes wouldn't be able to extend it anyway due to it only having a private constructor.)
I use an enum with no instances
public enum MyUtils {
; // no instances
// class is final and the constructor is private
public static int myUtilityMethod(int x) {
return x * x;
}
}
you can call this using
int y = MyUtils.myUtilityMethod(5); // returns 25.
Best practice is to throw an error if the class is constructed.
Example:
/**
* The Class FooUtilityService.
*/
final class FooUtilityService{
/**
* Instantiates a new FooUtilityService. Private to prevent instantiation
*/
private FooUtilityService() {
// Throw an exception if this ever *is* called
throw new AssertionError("Instantiating utility class.");
}
You can just use Lombok annotation to avoid unnecessary initialization.
Using #NoArgsConstructor with AccessLevel.PRIVATE as bellow:
#NoArgsConstructor(access = AccessLevel.PRIVATE)
public class FilePathHelper {
// your code
}
I recommend just disabling this rule in Sonar, there is no real benefit of introducing a private constructor, just redundant characters in your codebase other people need to read and computer needs to store and process.
Alternative using Lombok is use #UtilityClass annotation.
#UtilityClass was introduced as an experimental feature in Lombok v1.16.2:
If a class is annotated with #UtilityClass,
the following things happen to it:
It is marked final.
If any constructors are declared in it, an error is generated.
Otherwise, a private no-args constructor is generated; it throws a UnsupportedOperationException.
All methods, inner classes, and fields in the class are marked static.
Overview:
A utility class is a class that is just a namespace for functions. No instances of it can exist, and all its members are static. For example, java.lang.Math and java.util.Collections are well known utility classes.
This annotation automatically turns the annotated class into one.
A utility class cannot be instantiated.
By marking your class with #UtilityClass, lombok will automatically generate a private constructor that throws an exception, flags as error any explicit constructors you add, and marks the class final.
If the class is an inner class, the class is also marked static.
All members of a utility class are automatically marked as static. Even fields and inner classes.
Example:
import lombok.experimental.UtilityClass;
#UtilityClass
public class FilePathHelper {
private static String resourcesPath;
public static String getFilePath(HttpServletRequest request) {
if(resourcesPath == null) {
ServletContext context = request.getSession().getServletContext();
String serverpath = context.getRealPath("");
resourcesPath = serverpath + "/WEB-INF/classes/";
}
return resourcesPath;
}
}
Reference from official documentation:
https://projectlombok.org/features/experimental/UtilityClass
Although using #UtilityClass annotation will show issue on sonarCube.
So basic problem is "Java provide a default no-argument public constructor" for a class. now we have two solutions -
Remove #UtilityClass and make it static final class with private constructor.
Instead of using it as class, Use it as Enum .
but -
When the problem in sonarQube then use -
#SuppressWarnings("java:###")
"###" rule number.
Add private constructor:
private FilePathHelper(){
super();
}
public class LmsEmpWfhUtils {
private LmsEmpWfhUtils()
{
// prevents access default paramater-less constructor
}
}
This prevents the default parameter-less constructor from being used elsewhere in your code.
SonarQube documentation recommends adding static keyword to the class declaration.
That is, change public class FilePathHelper to public static class FilePathHelper.
Alternatively you can add a private or protected constructor.
public class FilePathHelper
{
// private or protected constructor
// because all public fields and methods are static
private FilePathHelper() {
}
}
make the utility class final and add a private constructor

Should I create protected constructor for my singleton classes?

By design, in Singleton pattern the constructor should be marked private and provide a creational method retuning the private static member of the same type instance. I have created my singleton classes like this only.
public class SingletonPattern {// singleton class
private static SingletonPattern pattern = new SingletonPattern();
private SingletonPattern() {
}
public static SingletonPattern getInstance() {
return pattern;
}
}
Now, I have got to extend a singleton class to add new behaviors. But the private constructor is not letting be define the child class. I was thinking to change the default constructor to protected constructor for the singleton base class.
What can be problems, if I define my constructors to be protected?
Looking for expert views....
If you extend a singleton class via inheritance, you'll have 2 instances of the singleton class running around should someone grab your singleton and the original singleton.
If the original singleton is conceptually really supposed to be a singleton, then using composition is probably the way to go. However, then substitutability is lost (your class is not substitutable for the original singleton; it just uses it).
Do you have a concrete example?
If you do that, it's not a singleton. But perhaps you don't really need a singleton.
This is not the Singleton Class. Imagine I can call getInstance() static method n number of times and I can have n objects of this class thus completely violating Singleton Pattern. To make it Singleton you should check whether object is already created or not in getInstance() method. If already created then you should ignore and do not create again. For example, you can so something similar, please ignore syntax mistakes, just a code to explain, can vary in different languages.
public class SingletonPattern {// singleton class
private static SingletonPattern pattern = new SingletonPattern();
private SingletonPattern() {
}
public static SingletonPattern getInstance() {
if(SingletonPattern == null) {
return new SingletonPattern();
}
}
Old question I know but happened to stumble upon this and think I can add something useful.
It is possible to have a protected constructor in a singleton class. If you want to have polymorphic behavior on your Singleton you can make it an abstract class, set the constructor to protected and delegate creation of the instance to one of the concrete sub classes.
I found the following example in the book "Design Patterns explained":
abstract public class Tax{
static private Tax instance;
protected Tax() {};
abstract double calcTax( double qty, double price);
public static Tax getInstance() {
// code to determine what implementing class to use
instance = USTax.getInstance();
return instance;
}
}
public class USTax extends Tax {
private static USTax instance;
private USTax() {
// instantation local members + Tax abstract class
}
public double calcTax ( double qty, double price){
// implementation
}
public static Tax getInstance() {
if(instance == null)
instance = new USTax();
return instance;
}
}

Are all final class immutable?

Are all final classes in Java immutable.
String and Integer both are final classes and both are immutable i beleive.
No, final means the class can not be extended. It says nothing about mutability. For example:
final class MutInt {
public int modifyMe;
}
No - a final class means you cannot inherit from it. It has nothing to do with mutability. The following class is final yet mutable:
public final class FinalMutable {
int value;
public void setValue(int v) { value=v; }
public int getValue() { return value; }
}
There is no keyword for immutability, it's more like a design pattern.
EDIT:
This means, there is no keyword, that makes a class immutable. To make a class immutable, you have to protect the internals by make them final or private.
The confusing thing is this: The final keyword has different meanings when used on a class then it has when used on a field/variable. The former means "this class can not be extended". The Second means "this variable (or reference) can not be changed".
Further to the other responses, if you look at the code for java.lang.String you'll see it contains a field: hash, which is mutable and is in fact computed and stored when hashCode() is called for the first time.
However, the class is still immutable: The hash field cannot be accessed directly or modified outside of the class.
Also, you may notice a common approach within the JDK is the implementation of immutable wrappers that can be used to expose an object's internal state without allowing it to be modified; e.g.
private final List<String> values;
public List<? get String> getValues() {
return Collections.unmodifiableList(values);
}
As has been said by the others before final does not make a class imuutable in Java though it plays a part in the immutability strategy. To obtain immutability you should follow the general guidlines:
ensure the class cannot be overridden - make the class final, or use static factories and keep constructors private
make fields private and final
force callers to construct an object completely in a single step, instead of using a no-argument constructor combined with subsequent calls to setXXX methods (that is, avoid the Java Beans convention)
do not provide any methods which can change the state of the object in any way - not just setXXX methods, but any method which can change state
if the class has any mutable object fields, then they must be defensively copied when passed between the class and its caller
The private field can't be accessed by sub class's overridden methods...So there is no way the sub class methods change the private field of super class...Then what is the use of making the immutable class as final?
Final keywords prevents the other classes to inherit it. Final keyword doesn't make it immutable but there are such condition as making the instance class members private as well final and by using getters and not using setters
A final immutable classes cannot be mutated. Here below it shows a non-final immutable class being mutated:
// a class not intended to be mutated
public class GoodClass{
private String name;
public GoodClass() {
this.name = "Good Class Neme";
}
public String getName() {
return name;
}
}
public class BadClass extends GoodClass {
private String name;
public String getName() {
return name;
}
// mutating state
public void setName(String name) {
this.name = name;
}
}

Categories

Resources