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.
Related
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.
This question already has an answer here:
Why declare a function argument to be final?
(1 answer)
Closed 5 years ago.
The keyword final can improve performance, when I design our project, I think if the field, method and class doesn't need to be inherited, I usually make them final, but shall i set the formal parameter of my method final too? I'm not sure...
Sometimes its nice to be explicit(for readability) that the variable doesn't change. Here's a simple example where using final can save some possible headaches
public void setTest(String test) {
test = test;
}
if you forget the 'this' keyword on a setter the variable you want to set doesn't get set. However if you used the final keyword on the parameter then the bug would be caught at compile time.
This question already has answers here:
Why might one also use a blank constructor?
(10 answers)
Java entity - why do I need an empty constructor?
(8 answers)
Why Default constructor need to declare in POJO file which has Parameterized Constructor while instantiating Object?
(5 answers)
Default constructor does not initialize the instance members of the class?
(7 answers)
Closed 5 years ago.
Is it okay to use an empty constructor in Java? For example, when loading the data from a MySQL database, I want to do something like:
ResultSet set = statement.executeQuery();
while (set.next()) {
Faction faction = new Faction();
faction.setId(UUID.fromString(set.getString("id")));
faction.setName(set.getString("name"));
}
Because I already have a constructor for the faction class,
public Faction(Player player, UUID uuid) {}
I was wondering if I can have a plain constructor and just set the values as and when.
Otherwise I could create a constructor using parameters that match the mySQL data (public Faction(String name, UUID uuid, String announcement..etc), to load in.. Not sure what is best practice?
If the object state should not change when the Faction class is instantiated, provide a constructor with args and removing setter is better.
In this way, you avoid undesirable behavior.
Now, according to your saying, you probably need to set many String parameters.
Doing it with a constructor is very error prone as you may do a mistake in the parameter order when you use it.
To achieve your need, you have two main ways :
using an empty constructor and then setters as you propose (desirable if the object is mutable)
if your object is immutable, you could use the Builder pattern to construct an immutable object (You write something like : Faction faction = new Faction.Builder().name(name).uuid(uuid).announcement(announcement).build();
It depends on your use case. If you dont want the class variables to change once you set them then in that case declare those variables as final and use the parametised constructor. If you want the variables to change once you set them, then use the default constructor with setters and getters.Both the options are perfectly fine.
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 = ...
}
}
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)