Accessing private fields within a class [duplicate] - java

This question already has answers here:
Private Member Access Java
(7 answers)
Closed 9 years ago.
I've encountered one interesting thing to me relating to the basics of Java.
Here's the code:
class Whoa {
private int n;
private void d() {
Whoa whoa = new Whoa();
whoa.n = 1;
}
}
Why the field n of object whoa is accessible? I mean, OK, we're in the class. But whoa is the separate object, I thought we have access only to the fields of a current object. Although I admit that if we have a method that takes a Whoa parameter:
private void b(Whoa w) {
w.n = 20;
}
we'll definitely have access to n. It's all quite confusing. Could anyone clarify this please?

The point of Java's access modifiers is protecting the internals of a class from code foreign to it. Since all instances of the same class share the same internal code, there would be little use in enforcing access restriction between them.
This the rationale of Java's class-level encapsulation.

As long as your are in the same class,you can access the private variables

For every new instance of the Object 'Whoa' that you create there will be an instance of 'n'. That 'n' can only be accessed from the instance of 'Whoa' (hence private)

Related

Is the correct terminology in Java attributes or class variables or class fields etc? Many thanks [duplicate]

This question already has answers here:
What is the difference between field, variable, attribute, and property in Java POJOs?
(11 answers)
Closed 1 year ago.
Is the correct terminology in Java attributes or class variables or class fields etc? Many thanks
This to confirm is for variables declared in the class Main...I've seen these variables called a few things and just curious what the correct term for Java would be?
e.g.
public class Main {
int x = 10;
int modelYValue;
String modelName;
Boolean joyous;
private int age = 28;
}
Those are instance members, or instance variables. When you create an object those members get created as part of it. Each object has its own instance member variables. See https://en.m.wikipedia.org/wiki/Instance_variable
Class member means the variables belong to the class, not to any object instance. Static variables are class members.
People tend to confuse these and say class member when they mean instance member.

How to define a "good" get() method for a private variable in a class? [duplicate]

This question already has answers here:
Why make defensive copies in getters inside immutable classes?
(7 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 3 years ago.
I'm learning Java and I have some doubts.
If defined a class with a private variable like
class test<A>{
private A var;
...
public A get(){
return var;
}
}
Is the get method wrong?
I think so because with this definition I can modify the variable "var" like
test<A> x = new test<A>();
A temp = x.get();
temp.set(*something*);
At the end x is changed (I tested it using Vector as A). If I understand correctly, this works because object reference (I miss C pointers, sob). Am I wrong? Maybe I don't understand the purpose of the keyword "private"! Thanks in advance!
Edit: I have no problems with "pass-by-reference" and "pass-by-value". I have doubts defining get() method for a private variable in a class (you don't say?). Please stop linking Is Java "pass-by-reference" or "pass-by-value"?
If your getter method is returning a reference to a mutable object, then this greatly weakens the quality of the encapsulation provided by your class, because it becomes possible to modify the state of an instance of your class without calling a method of the class.
One standard strategy to guard against this problem is what J. Bloch calls defensive copies (Effective Java, 3rd edition, Item 50: "Make defensive copies when needed").
This would mean creating a copy of var in the getter method, and returning that copy instead. How to do this depends on the design of A.
Because A is a type parameter, making a copy of the instance requires additional support in the design. To see how to achieve this using Java's cloning mechanism, see my answer to the post "Does it make sense to create a Copyable type interface instead of using Cloneable?".
If this is a problem, you can create a façade to protect your variable
public class Facade extends A {
A myObj;
public Facade (A obj) {
myObj =
}
public A get(){
return myObj.get();
}
public B set(Object val) {
throw new RuntimeException("Setting is not allowed");
}
}
This might be a bit too much detail for just starting, but you might review class java.util.concurrent.atomic.AtomicReference<V>, which is very similar to your example.
Generally speaking, placing instance variables in private variables, while providing access to the variable using a getter and a setter, is standard practice.
Note that your class name should be capitalized, type parameter 'V' is more standard, and the variable name would more usually be 'value'. Also, try to pick a more communicative name for the class. (Type parameter type variable could be 'ValueType', which would fit some preferences. But, single character type variable names are more usual.)
public class Wrapper<V> {
private V value;
public V get() {
return value;
}
public void set(V value) {
this.value = value;
}
}
I'd add some other point here: as others have said, you hand out the object reference and it can be modified, which could be bad.
Object orientation is about keeping the data and the code that works on it in one place. If you need getters, think what the callers of the getters need to do, and whether that action should rather be a method on the class that has the data. Your code could suffer from the Feature Envy code smell, as it violates the Tell, Don't Ask principle.
To fix this, remove the getter, and introduce new methods as needed. For example, if you have some data object that needs to get printed, you could pass the Printer to the object and have it print itself to the given Printer.
If you're dealing with a collection class (just a guess from your template parameter), you may need to keep the getter, but then you're probably not concerned with the caller changing the value anyway.

What is the purpose of parameterized constructors? [duplicate]

This question already has answers here:
what is the use of a parameterized constructor in java?
(7 answers)
Purpose of a constructor in Java?
(12 answers)
Closed 4 years ago.
Just why are they used? I'm a beginner by the way. I understand default constructors that initialize values because it makes logical sense, but why use a constructor with parameter to say that an instance variable age for example is equal to a. What is the purpose? What happens without it and only the initializer constructor? Other questions asked on here do not make sense tome
For example:
public class MyCats {
private int age;
private String name;
public MyCats(int a, String n) { // why do I need this?
age = a;
name = n;
}
public MyCats() {
age = 0;
name = "";
}
}
That's for easily creating your class without needing extra code. For example, instead of doing:
MyCats a = new MyCats();
a.setAge(12);
a.setName("Foo");
You can just do:
MyCats a = new MyCats(12, "Foo");
Simpler, hum?
Other reasons you might prefer the later, if shortness is not enough:
You can initialize all calculated fields that depend on several fields inside the constructor, using the values provided.
You can validate input and thrown exceptions in case of invalid arguments, even for checks that requires multiple arguments for that.
You must do that if your fields are final and your class immutable, in which case there is no setters available.
Mostly in the last case, it's very useful to be able to check for correctness upon construction and disallow any objects from being in a invalid state, saving lots of errors later on.

Is it bad practice to have public data objects? [duplicate]

This question already has answers here:
What is the use of encapsulation when I'm able to change the property values with setter methods?
(17 answers)
Closed 5 years ago.
One of NASA's coding rules for writing safety critical programs is:
Declare data objects at the smallest possible scope
My question is, what if I have a large data object that I would like to pass around. Should I parse the object to a smaller object whenever it goes out of scope (e.g. package-level)? What if it needs to be passed to multiple packages? Do I have to create a package-level object every time?
EDIT: To clarify, I was referring to POJOs, perhaps obtained by deserializing an API response. All this time I've been making POJO classes with public fields.
Clearly, if objects of a certain class must be manipulated in different packages then either the class itself or some interface it implements must have public visibility. But that doesn't mean you need to expose every little detail about the class to public scrutiny or interference. The rule is just saying that you should not, nay, must not, expose every little detail.
Obviously some details must be publicly visible or else the class wouldn't be too useful. But there are almost always some other details which are none of the public's business, and the rule is telling you that you need to identify which details are which and not make public those details which are, in fact, none of the public's business.
The rule also relates to scope of variable declarations: declare things in the smallest scope possible. For example, if you need a variable to hold onto a result temporarily, declare a local variable inside the method where it is needed:
// YES
public class C {
private void meth1(){
int x = ...
}
}
not an instance variable in the containing class:
// NO!
public class C {
private int x; // an even worse sin would have been to make x public
private void meth1() {
x = ...
}
}

A tricky question of simple Java: variable scope

I am not new to java and C#. I thought I understand the concept of variable scope until recently I was asked this question in an interview:
public class Q{ //starting y scope
static int x = 11;
private int y = 33; // Just added a “private” modifier to make it clearer.
public static void main(String args[]){
Q q = new Q();
q.call(5);
}
public void call(int x){
Q q = new Q();
this.x = 22;
y = 44;
System.out.println("Output: " + Q.x);
System.out.println("Output: " + q.x);
System.out.println("Output: " + q.y);
}
} //ending y scope
Define the output of this program.
I answered the question during the interview that the output would be a runtime exception. To my understanding, y is declared private, and the instance method call() is trying to access the instance private variable y of another instance of class Q. How could that happen at all!? However answering this question wrongly didn't affect my interview too much because this is the kind of "tricky basic" question. But, answering wrongly means my years' Java experience needs rehab, that's terrible!
Could someone help me on this matter? I would be so much appreciated!
You can access private members of your own class, even from a different instance of the class.
private just means it can't be accessed by objects of another class, not any other objects. So one Q object can access the private members of another Q object.
[Note that if this were illegal, this would trigger a compiler error, not a runtime exception.]
Private variables are accessible within the program text of the declaring class. It doesn't matter if one instance tries to access variables in another instance, so long as the code is within the same class.
From the JLS section 6.6:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
private means that classes outside of this class cannot see the variable. Within this class definition, all methods and variables can be accessed.
Access restrictions should be enforced compile time not in run time, so the compiler should prevent compiling the code if it was wrong.
But an access modifier is applied on class level, so you can always access a private member from the class it self.
When you clone an object this is often useful since you can just set a bunch of values in the clone directly, which might have been hard to access otherwise. Also when comparing objects with an Equals method it can be quite handy that it is the class not the instance that defines the access restrictions.
As it was already pointed out, private members of the other instances are accessible from the class. Also, you were incorrect about the runtime exception: there will be no runtime exception even if you modify the code so that you try to access a private member of another class, the code will just fail to compile.
I think there will be a compilation problem because the attribute static int x = 11 is declared static and in the method call, the variable x is accessed by a this. You cannot make a this to a static variable in a class.
There is no problem with the private member y.
The correct "interview" answer is that whoever wrote code like this should be fired! Lousy class name, useless comments about y scope; non-standard use of "this" which should really only be used for instance variables, not class variables; re-using 'q' in the main and call methods.
It reminds me of the obfuscated C++ contests, exactly the sort of nonsense Java was designed to avoid.
Worse than this, though, is that it's very difficult to tell from the comments and the answers what the output of the program should be. Do I go by the '6' on the comment by Kevin?
I wish an admin would refactor all this. And I would tell an interviewer (if this really is an interview question, which I doubt) that we should run the code, get the answers, and then create a simple test to confirm that the answers don't change when we refactor the code to conform to standard usage.

Categories