Why can private members in Java be modified from another class? - java

In the following example, x can be changed by class B even though it's a private member of class A. What's the reason for this?
import java.util.Date;
class A {
private Date x;
public A(){
super();
x = new Date();
}
public Date getDate(){
return x;
}
public void print(){
System.out.println(this.x);
}
}
class B {
public static void main(String[] args){
A a = new A();
a.print();
Date d = a.getDate();
d.setMonth(12);
System.out.println(d);
a.print();
}
}
The output is:
Initial date generated by A
Date changed by B
Date changed by B (why does it change a private member here?)

private prevents a variable from being accessed directly by another class. You cannot write d.x to read or write to x.
If the class chooses to return a reference to x via a public method, though, that's it's own choice to pierce the veil of privacy. Nothing stops A from allowing x to be read from a getter or modified from a setter.
In recent years the Java community has recognized the problem with this: namely, if you return a reference to a private mutable object, you open the door for your class's internal state to be mucked with without its knowledge. To protect against this, it has become good practice to make classes immutable whenever possible.
Indeed, Date is a perfect example of a poorly-designed mutable class. The java.time package introduced in Java 8 added a slew of immutable time and date classes to replace Date. You can now return a private Instant and not worry about callers being able to change it.
It's important to point out that immutability comes from how a class is defined. It's not a language-level feature like private. Confusingly, final can be used to make variables immutable, but applying it to a class does not make the class immutable (it makes it unextendable).

You're not changing the private property. Try this and see it fail:
A a = new A();
a.x = someOtherValue;
But the A class does allow you to read the property:
public Date getDate(){
return x;
}
And the Date class allows you to set its property:
d.setMonth(12);
No private member is being accessed outside of a class here. Date and A are two different classes.

This did not change x it is still pointing to the same object. What was changed is the object itself.

You are confusing reference with value.
The Date object referred to by x never changes and the field x is inaccessible from the sub class - ie the sub class can't assign a different Date object to x.
However, the getter allows you to access the object referred to by x, and (perhaps unexpectedly) Date objects are mutable - that is a Date's value can be changed. It's still the same Date object, but the instant in time it represents is different.
IMHO, the Date class is "broken"; it should be immutable.

The getDate() method is public. The getter method is public, that is you can now access the object and change its value. Date d and Date x are only reference to those objects not the actual objects.

Related

How does upcasting works in Java?

I was going with the concept of upcasting and downcasting in java, which are also referred as widening and narrowing.
UpCasting (Widening) happens automatically from derived class to base class. i.e if it has a is-a relationship.
Downcasting has to be done explicitly for run time check.
Okay, I got the concept and everything. But, how its working in this case?
public class ObjPair {
Object first;
Object second;
public ObjPair(Object first, Object second) {
this.first = first;
this.second = second;
}
public Object getFirst() {
return first;
}
public Object getSecond() {
return second;
}
public static void main(String[] args) {
ObjPair objPair = new ObjPair("A",2.2); // Goes widning conversion
System.out.println(objPair.getFirst());
System.out.println(objPair.getSecond());
}
}
ObjPair objPair = new ObjPair("A",2.2);
This is going through upcast, String to object and Double to object and the state gets store in the objPair. Great..!!!
Now,when i do objPair.getFirst() and objPair.getSecond(). It returns me A and 2.2.
How does it remember the string and double, widening/upcast is supposed to remember the super-class states and methods.
How is it able to access sub-class types and values?
Casting of object references does not change the object. It simply allows assigning it into a reference of a different type. The object itself remains the same.
In your case, it needs two Object references, it checks compatibility (no problem there), and then the references are set in variables of type Object. The instances themselves do not change. If they have methods that override those of Object, then the overriding methods will be called.
Thus, when it comes to the part where it prints the object, it simply uses String.valueOf, which calls the object's toString() method. The instance accessed from the Object variables is actually a String object, and String overrides toString() to return itself. Double also overrides toString. These overrides are called, as the instance is still an instance of String and an instance of Double. Only the reference is Object.
Note that you also have a cast from double to Double there. This implicit boxing does change the object - it takes a primitive and creates a new Double from it.
If you simply test this code:
public class Main {
public Object first;
public Object second;
public static void main (String[] args){
Main a = new Main();
a.first = new String("foo");
a.second = 5;
System.out.println(a.first.getClass().toString());
}
}
It outputs class java.lang.String. You can see that it isn't stored as an Object. This is achieved through the use of metadata.
Keep in mind: the object in memory is what it is. If you create a Double object, then it is a Double object resembling the numerical value.
The fact that the variable that holds the reference uses a super type doesn't affect the object referenced to at all!
In your example, the auto-boxing create a Double object under the cover, andgetSecond() returns a reference to that Double object.
That is all there is to this.
Okay so here it is, lets take an example. You have a big square box,named Object and another small box. If you keep this small box inside your big box,all the properties of small box and big box are in the big box.
Then inside the small box,there are two sticks,you are labeling the first stick as 'A' and second as '2.2'.
Now the big box can see what is inside of small box. Now for that instant, the small box is having two sticks and labelled as the way they are.
(Rememeber the Object class is always the super class/parent of every classes in java).

convert mutable variable to immutable in java with less pain

sometime i have no choice to use mutable variable instead of immutable variables i know how many ways can create immutable vars but i wonder this way also correct its really convert mutable to immutable and i dont use concurrency or multithreading in my code just Curious?
public class Config implements FindIt {
....
private final class DateHolder{
private final Date dateContainDateObject;
DateHolder(String date) throws ParseException {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
dateContainDateObject = dateFormat.parse(date);
}
public Date getDate(){
return dateContainDateObject;
}
}
}
this is nested class and i use it like
private DateHolder holder;
and fill the holder variable in Config constructor class so holder variable are ThreadSafe ?
Date is a mutable object. Making it final means you can't change the reference to it, but you can still change what's at the reference (java.util.Date/Calendar nastiness strikes again, switch to the Java 8/Joda Time way if you can).
Don't expose any references to the Date member to the outside world. Instead make a defensive copy and pass that back instead. You might consider saving the time value as a final long instance member and only instantiating a Date when you need it.
can say is safe when you make class private and non-static, when you create form Config class you have only one DateHolder .
http://www.javapractices.com/topic/TopicAction.do?Id=29
why is static inner class singleton thread safe
http://www.javatpoint.com/how-to-create-immutable-class

Usage of final in java

I was wondering what the difference is between
public final type attribute_name;
and
private type attribute_name;
public type getA_name() {
return attribute_name;
}
Basically I want to make an attribute read-only, so it can't change after it has been initialized.
Do I make it public final, or do I make it private, and only make it accesible through a get method (without a set method)?
When it's not final but private, the class itself is able to change the value.
A final field MUST be set before the constructor exits. Once set, the reference cannot be modified (the value cannot be reassigned). Emphasis on the cannot be reassigned. This means that while the reference cannot change, the value itself can change.
This is legal:
final List<Integer> list = new List<Integer>();
list.add(5); // the value of list changes, but the reference doesn't
This is not:
final List<Integer> list = new List<Integer>();
list = new List<Integer>(); // may seem sort of redundant but the compiler won't allow it nonetheless
A private variable with a only getter can be reassigned internally by the class that holds it (but it's not visible externally so it cannot be reassigned outside the class holding it). Also, outside the class the reference is inaccessible so the variable cannot be modified except by the class holding it.
A final variable cannot be reassigned anywhere, but if it's public, another class can still access the reference and change the value of whatever object it points to.
If you don't want the variable to be reassigned after initialization as you described, use both final and private.
Use final for something like this:
public class User {
private final long registrationTimeMillis;
public User(/* various parameters probably would be here */) {
registrationTimeMillis = System.currentTimeMillis();
}
public long getRegistrationTimeMillis() {
return registrationTimeMillis;
}
}
We don't expect that a user's registration time will change, so it makes sense to not allow it to change after construction.
Use private with no setter for something like this:
public class VendingController() {
private int drinksStocked = 0;
private int drinksDispensed = 0;
public void dispenseDrink() {
drinksDispensed++;
}
public void stockDrinks(int numberOfDrinks) {
drinksStocked = getDrinksRemaining() + numberOfDrinks;
drinksDispensed = 0;
}
public int getDrinksRemaining() {
return drinksStocked - drinksDispensed;
}
}
We don't want the value of drinksDispensed to change except when dispenseDrink() or stockDrinks(int numberOfDrinks) is called. It still needs to be able to be reassigned by it's own class when the vending machine is refilled though, so we shouldn't make it final
With respect to using public final, generally in Java that's only done for constants and that static keyword is also included since constants shouldn't be dependent on an instance.
An example of when it makes sense to use public static final
public class UnitConversions {
public static final double CENTIMETERS_PER_INCH = 2.54;
}
It could then be used in a method as follows
public double convertFromCentimetersToInches(double centimeters) {
return centimeters / UnitConversions.CENTIMETERS_PER_INCH;
}
Best of luck OP and happy coding.
More reading on final fields
This depends on some factors.
If this is a real constant that is known before and will never change, then use final. In Java final fields can be initialized in the constructor as well, so if your value is known at construction time then you can use final too.
If this value gets set (once, multiple times) during runtime then use private + getter.
The final modifier allows a field to be assigned only once - it cannot be changed after that and it has to be set at during object construction (that is, before the constructor returns).
If you want to make the field read-only, use the principles of information hiding: make it private and provide a public getter that returns the field (or a copy of it for non-primitive types).
You should use public final only for true constants. Even if your field is immutable because of final it is often a good idea to still make it private.
The correct way is to think in the future. What would help you achieve your goals? Maybe later you would also like to give that variable a value. If I were you, I'd do this by creatin a get method and keeping the variable private.
Full documentation for final keyword : http://en.wikipedia.org/wiki/Final_(Java)
Depends on where you want to access it from. Public variables can be accessed from any class within the project and package where private can only be accessed from the class where the variable is.
The 'final' operator makes it permanent and read-only.
Let's assume that type is a reference to an object, not a primitive type.
public final type attribute_name means that attribute_name cannot be reassigned to refer to something else. But attribute_name can be used to call a method that changes its state.
In private type attribute_name, only methods within the class can call methods on attribute_name.
So if you want it to remain constant, use approach (2). Limit the public methods to ones that ultimately call methods on attribute_name that don't modify its state.

In Java how should I compare an object to a const value?

I've created my own MyDate class. It basically wraps a Long value with some pretty toString() functions. I've implemented equals() and compareTo(). my program reads some data and instantiates object of classes that hold this MyDate class. Problem is that sometimes that data is bad so I created a public static final long NODATE = Long.MIN_VALUE; so that I could initiate a new instance that is empty (replace the null in the containing class so to avoid NullPointerExceptions). I've also implemented a constructor with no arguments that inits the Long value to NODATE.
My Problem:
I want to check if a MyDate is valued as NODATE. I can't compare to NODATE since it's Long and not MyDate. One way to do this is:
if someObject.myDate.equals(new MyDate()).
But it seems like a waste to create an object just to make the comparison? Another way is to implement MyDate.amINoDate() method.
Is there another way? I was thinking of creating an static instance of MyDate that is inited to NODATE and to compare to it. But how can I compare my non static objects to this static object?
class MyDate {
public static final MyDate NODATE = new MyDate(Long.MIN_VALUE);
// ...
}
// ...
if (someDate.equals(MyDate.NODATE)) // ...
Thanks maskacovnik.
You can also add a method to MyDate like:
public boolean isNodate() {
return internalLongDate == Long.MIN_VALUE;
}
Add a method to MyDate:
if (someDate.isNoDate()) {
...
}
Also: personally I would avoid the Long.MIN_VALUE and use null.

How does Object Oriented Programming work?

I am not sure about some things in OOP.
If I have Class1, which has some private field, for example private Field field1, and make
getField1 () {
return field1;
}
then I have some class with constructor
public Class2 (Field field) {
someMethod(field);
}
And then I call constructor of Class2 in Class3 like:
Class2 cl = new Class2(instanceOfClass1.getField1());
And now the question: Am I working with field1 of instanceOfClass1 in someMethod(field)?
This depends on whether field is a value or a reference.
Value types are copied when passed as parameters. Reference types are not; the function is simply handed a "reference" that points back to the original value, and any changes that it makes are reflected in the original value.
Whether a given type is value or reference depends on your particular programming language. Generally speaking, basic integer and boolean types are usually value types, and everything else is up in the air -- some languages make strings values, and others treat them as references, etc.
Edit: Since you mentioned you're using Java, here's a short program that demonstrates value and reference types:
class ClassOne {
public int myInt;
}
class ClassTwo {
public int myInt;
public ClassTwo(ClassOne c)
{
myInt = c.myInt;
c.myInt = 3;
}
}
public class main
{
public static void main(String[] args)
{
ClassOne c = new ClassOne();
c.myInt = 1;
System.out.println("C1: " + c.myInt);
ClassTwo c2 = new ClassTwo(c);
System.out.println("C2: " + c2.myInt);
System.out.println("C1: " + c.myInt);
}
}
Running this program will give the output:
C1: 1
C2: 1
C1: 3
In this program, both ClassOne and ClassTwo contain an integer field -- a value type. ClassTwo takes a ClassOne parameter -- a reference type -- in its constructor, and sets its own integer field based on the value of the ClassOne object it is given, and then changes the ClassOne object's value.
Because classes are reference types, changing the ClassOne object in the ClassTwo constructor causes the original object to be changed. (In the main function here, that's c.) But because integers are value types, even though c2 changes the value of c.myInt in its constructor, because it sets its own value beforehand, c2.myInt isn't affected: it retains the original number, because it was copied rather than referenced.
Hopefully this helps clear things up a bit.
You're working with the value contained in it. If it is a mutable object then yes, it is possible to change the state of the instance of Class1 from outside, which violates data protection principles. This is why you should copy mutable types before returning them.
I had to reread your question two or three times to make sure I understood what you're asking.
To recap:
There is Class1 which contains an field attribute (of type Field?) which is sent back by it's getField1() method.
There is then Class2 which is apparently has a constructor that accepts an object parameter of Field type and contains a method that uses an instance of Field to trigger a local method in this class.
You then use a third class to instantiate Class2 and initialize it using an instance of Field using the getField1() method from an instance of Class1.
In the case of Java, providing you've done the necessary instantiation this would mean that the Field instance in Class1 is being used throughout the process. You can verify this using a System.out.println() (this will give you an # symbol with a series of weird numbers) or using the a.equals(b) method common to all objects.
Here is an interesting link about passing objects by value:
http://www.javaranch.com/campfire/StoryPassBy.jsp

Categories