Class variable: public access read-only, but private access r/w - java

In my current project I have a class which stores its Instance in a variable. This Instance should be accesible by all other classes in the project, but it may only be altered by its own class.
How can I achieve this?

Write a public getter but no public setter. And the field itself private

In short that is called immutable object, state of Object cannot change after it is constructed.
String is a common example of immutable Class.
Make a class immutable by following-
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.
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.

Someone suggests "public getter but no public setter for the private field."
Caution: This would only work if the field is primitive type.
If it is an object with setters, the content can still be modified; thus not read-only.
It will be interesting to see Java language provide some constructs to make a return type read-only without having to do a deep-copy / clone.
i'm imaging like
ReadOnly getEmployee() {
...}

The boilerplate code for instantiating a singleton can be found in many places, see for example http://www.javacoffeebreak.com/articles/designpatterns/index.html
Be aware that many consider the singleton to be an antipattern because it's pretty hard to get rid of once your application is littered with references to the singleton.

Related

can we make a method as private in encapsulation in java?

To achieve encapsulation we make members as private (variables) and use getter and setter methods for data hiding and that's how we achieve data hiding. So in the same way can we make a method as private and access it with getter or setter method ? (or is there any other way to do it)
In Java private methods are the methods having private access modifier and are restricted to be accessed in the defining class only and are not visible in their child class due to which are not eligible for an override. However, we can define a method with the same name in the child class and could access in the parent class.
I don't think there can be getters and setters method for the same reason.
Certainly you can define a method as private, so that it can only be called (essentially) from other methods in the same class. This is a pretty common practice. For example, I might provide a method getFoo(), where the actual value of foo is not not simply an instance variable, but something derived by calculation using other (private) methods. To the user of the class, getFoo() returns some data called 'foo', but it can't see where it comes from -- whether it's stored, or derived, or some combination.

Immutable class in Java

As per many documentations, I have seen that an immutable class should have the following features:
class should be final
all the methods should be final
all the variables should be final
there should not be any setters
But my questions are:
What if I have a class with only final variables?
If I do have setters also, I cannot change the state of the Object as I have all the final variables. So how will this affect immutability?
How can inheritance change the object state in this case?
1.What if I have a class with only final variables?
That will get you far but not all the way. The types of those variables also need to be immutable. Consider for instance
class MyImmutableClass {
// final variable, referring to a mutable type
final String[] arr = { "hello" };
// ...
}
This allows someone to do
myImmutableObject.arr[0] = "world";
and effectively mutate objects of your immutable class.
Also, it's recommended prohibit extending the class (because there's no way to force subclasses to be immutable). See answer to your third question below.
If I do have setters also, I cannot change the state of the Object, As i have all the final variables. so how will this affect immutability.
That's right. If all variables are final, standard setter methods can't exist.
how can inheritance change the object state in this case?
A subclass can't change the state of final fields of the super class. But there's another issue with inheritance.
If you have an immutable Animal subclassed by a Dog, and the Dog has a setDogsName method that mutates the object, then in effect you may have Animal objects (of type Dog) that are in fact mutable.
In other words most (all?) benefits of immutability is lost if an immutable class is open for extension: If you receive an Animal as a parameter to a method for instance, you can't assume it's immutable. You can't safely put Animal objects as keys in hash maps, etc.
Basically the original statements are a bit redundant, which is why I think they are a bit confusing:
A final class can't be extended, so it's redundant to also mark the methods as final
If all variables are final, then it's kind of redundant to say that there should be no setters.
Also, these are sufficient constraints, but not necessary. You can for instance have immutable classes without final variables / final field types as long as they are private, never changed internally and never leaked to outsiders.
If i do have setters also,i cannot change the state of the Object, As
i have all the final variables. so how will this affect immutablity.
final is at reference level and immutability is at instance level.
class someMutableClass{
final List someList;
}
In the above piece of code. If the reference of the list escapes, then anyone can do :
someList.add(someValue)
But they cannot do :
someList=someOtherList;
That is the difference.
how can inheritence change the object state in this case?
The child class can access certain fields of the parent class and then change it. You can can make a parent class reference point to a child class object and modify its fields. So, to ensure immutability, you have to ensure that the child class doesn't alter anything in the parent. So make it final.
An immutable class is one that you cannot change. Achieving immutability is a matter of eliminating possible ways of changing an object's state. That can be achieved by a combination of structural and behavioural means.
But first, lets look at the "should have" list:
"class should be final" - This may be advisable, but it may not be strictly necessary ... or even desireable. An instance1 of a class can be immutable even if instances of some subclasses are mutable. It all depends on which classes need to be immutable, and that depends on the context.
"all the methods should be final" - Neither necessary or sufficient. If the class is final then it is unnecessary. If the class is NOT final, then it is not sufficient. (You can add methods with different signatures in a subclass.)
"all the variables should be final" - Neither necessary or sufficient. You can have an immutable class whose fields are not final, and a mutable class whose fields are all final.
"there should not be any setters" - It depends on what you mean by a "setter", but once again this is neither necessary (for some models of mutability) or sufficient.
Your Questions:
1) What if i have a class with only final variables ?
That is not sufficient to guarantee immutability. For example, if one of the final variables is an array, then the state of that array could be changed, thereby changing the state of the object as a whole. This could be done by a setter (or any other method of the class), or if the class is a "leaky abstraction" then it could done by external code.
2) If i do have setters also,i cannot change the state of the Object, As i have all the final variables. so how will this affect immutablity.
See above. Declaring all fields as final is not a guarantee of immutability. A setter could change the state of a mutable component of the object.
3) how can inheritence change the object state in this case?
It can't1. But that's not the point.
The reason for making an immutable class final is to stop someone creating a mutable subclass of the class.
Why does that matter?
Well, suppose that a method requires parameters to be immutable (e.g. for security). If you declare it with an immutable class that is not final, then someone create an mutable subclass and pass an instance of that instead of the original immutable class.
This is the main reason why (for example) the String class is final.
1 - I need to qualify this. It depends on whether we are talking about instances whose class is A, or about instances that are type compatible with A. I'm talking about the former. The fact that there is a mutable subclass does affect the mutability of an instance whose class is A.

How to make the return immutable in JAVA

I have an object such as
public class ABC {
private String a;
private String b;
private String c;
//getters and setters
}
This object is returned from a method in the collections such as ArrayList<ABC>.
I just want to make the return immutable without changing anything in the object. Can anyone please help me with this?
Don't provide setters (mutators), make immutable attributes private, only provide value assignment via constructor.
You can always declare your immutable attributes final. So you can only assign them values once and can't change them later.
You cannot make an object immutable if its class provides for mutation. Objects always offer all the capabilities defined by their classes.
Therefore, if you want an immutable object then you need an immutable class. If you cannot change the class in question, then a wrapper class such as #duffymo described could serve that purpose. Note, however, that objects of such a class are not interchangeable with objects of the wrapped class, and also that somehow you need to provide for applying the wrappers.
If you need objects that are fully interchangeable with objects of class ABC, then you're stuck with the fact that ABCs are mutable, therefore anything interchangeable with ABCs is mutable, at least with respect to the mutable aspects of ABC. Then it comes down to why you want immutability. If the point is to avoid mutating the object referenced by the List, then copying those objects (to whatever depth is appropriate) is an alternative.
As a third alternative, if the target class has no non-private fields then you might be able to create a subclass, overriding the setters to be ineffective or to throw some variety of unchecked exception. In that case, note that
Such a subclass is not good form, and its instances are not truly interchangeable with instances of class ABC.
If class ABC has accessible properties of mutable types (e.g. mutable containers), then you may need to do something to prevent those objects from being mutated, too. Recursively.
Yes, this is a big mess.
Use interfaces with only getters
A is your concrete (impl) class
Coding to interfaces?
public I getA(){ retrun AImpl();}
where
public interface I { public String getOne()}
public AImple implements I {...}
The only "Change" in your current class would be "implements I"
JDK and Apache commons use decorators
http://grepcode.com/file/repository.jboss.org/nexus/content/repositories/releases/org.jboss.embedded/thirdparty-all/beta3.SP15/org/apache/commons/collections/list/UnmodifiableList.java
Another solution
Clone your object and return it, that way copy is changed and original object remains intact

Java - is it bad practice not to have a class constructor?

I want to make a helper class that deals with formatting (i.e. has methods to remove punctuation and convert between types, as well as reformatting names etc.). This doesn't seem like it will need any fields - its only purpose is to get passed things to convert and return them, reformatted. Is it bad practice to leave out a constructor? If so, what should my constructor be doing? I was looking at this link and noticed that the class it describes lacks a constructor.
Is it bad practice to leave out a constructor?
Yes - because unless you specify any constructors, the Java compiler will give you a constructor with the same visibility as the class itself.
Assuming all your methods are static - which seems likely unless you want polymorphism - you should make your class final and give it a private constructor, so that other developers don't accidentally create an instance of your class, when that would be pointless. When thinking about an API, any time I can remove the ability for developers to do something stupid, I do so :)
So something like:
public final class Helpers {
private Helpers() {
}
public static String formatDate(Date date) {
// etc
}
}
Note that by taking polymorphism out of the equation, you're also removing the possibility of changing this behaviour for tests etc. That may well be fine - I'm not a believer in "no statics, ever" - but it's worth considering.
Any class that has all the methods which do not have or need any state is free to reduce the visibility of constructor by making the constructor private.
Example java.lang.Math class in Java.
As java.lang.Math has all static methods which do similar job as your class they have declared the constructor as private so that nobody can accidentally create the instance of that class.
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
Not bad practice. but the example that you have given doesn't have any member variables that can be used in an Object context. In such situations, it's best to have static methods because then you don't need to allocate memory to create objects for the class before calling the methods.
Compiler will generate a default constructor (with no parameters) for you. If your class has not state and does not extend a class which needs initialization, you can let it without declaring explicit constructor
no its good to leave out a constructor as there aren't any instance variables in your class!
constructors are meant to initialize the instance variables!
still if you skip the constructor, compiler anyways inserts the default constructor which is fair enough!!
You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of Object, which does have a no-argument constructor.
Java Official Document: Providing Constructors for Your Classes
Usually it is a good coding practice to define your constructor in the class though each class has a default constructor .
But if you do not have any special need to use a oveloaded constructor or to make any singleton pattern then you can remove the constructor .
If you are using static methods in your case then also you dont have any need to define constructor , as you do not need to have object of this class .

using a variable in two different java classes

I was wondering if it's possible to use a variable of a java class in another java class.Suppose variable Time is defined and calculated in Class A, how can I use it in Class B?
Other answers have suggested increasing a variable's visibility. Don't do this. It breaks encapsulation: the fact that your class uses a field to store a particular piece of information is an implementation detail; you should expose relevant information via the class's API (its methods) instead. You should make fields private in almost all cases.
Likewise, some other answers have suggested possibly making the variable static. Don't do this arbitrarily. You need to understand what static really means: it's saying that this piece of information is related to the type rather than to any one particular instance of the type. Occasionally that's appropriate, but it's generally a road towards less testable code - and in many cases it's clearly wrong. For example, a Person class may well have a name variable, but that certainly shouldn't be static - it's clearly a piece of information about a single person.
You should think carefully before exposing information anyway - consider whether there's a wider operation which the class in question could expose, instead of just giving away its data piecemeal - but when you do want to expose a field's value, use a property. For example:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
By exposing it via a method, you can later change the implementation details without breaking existing clients.
Then from another class, you'd just call the getName() method:
// However you end up getting a reference to an instance of Person
Person person = ...;
String name = person.getName();
If you do have a static field, you can expose the value in the same way, but with a static method, which you'd call using the class name.
Be careful about returning values which are mutable, e.g. java.util.Date. This is another reason for using a getter method instead of allowing direct access to the field - you can make the method return a defensive copy where you need to.
If it is declared as public, you may use ClassA.yourVariable. On the other hand, for private access modifier, include the getter to your ClassA. On the ClassB, call ClassA.getYourVariable().
Also read about access specifiers in Java it might help.
If the variable is static, you can refer to it as A.Time from any code that has access to the variable. There's only one Time value for all of class A. If it is an instance variable, and you have an instance a of class A, you can refer to the variable as a.Time. There's a separate value for each instance of class A.
This is subject to Java's access rules:
if the field is public, any code can access it (this makes public variables kind of dangerous unless they are also declared final)
if the field is protected, only code in the same package or in a subclass of A can access it
if the field has default access, only code in the same package as class A can access it
if the field is private, only code in class A (including inner classes of A) can access it.
Alternatively, you can provide an accessor method in class A:
public class A {
. . .
public class getTime() {
return this.Time; // the "this." is optional
}
}
If you declare your Variable as public or static you will be able to access it from another class.
WHICH IS A VERY VERY BAD IDEA :)

Categories

Resources