Assign default value to reference variable - java

In Java if we declare primitive variable (not local) like int, float etc and do not initialize them, then they get initialized by their default values. Can we achieve something like this for reference variables? For example if I have an employee class which contains two int variables and in another class if I have created only reference of the employee class so is it possible that int variables get initialized by zero?

In Java if we declare primitive variable (not local) like int, float etc and do not initialize them, then they get initialized by their default values.
No, they don't. Fields do, both instance fields and class fields, but not variables.
Can we achieve something like this for reference variables?
Reference fields get the same behavior. The value they're initialized with is null.
For example if I have an employee class which contains two int variables and in another class if I have created only reference of the employee class so is it possible that int variables get initialized by zero?
If by "created a reference" you mean you've created an Employee instance, then any fields in that instance will be initialized to their defaults unless the Employee constructor gives them a different value.

Fields are initialized to null if they are from some "type" (other than primitive types), anyway if you provide default values in your "default" constructor for that class in particular you can override the default null values for those.
final class Employee {
private String firstName;
private String lastName;
// You can have more constructors here
public Employee() {
firstName = "Default Value for First Name";
lastName = "Default Value for Last Name";
}
// Getters, Setters
}

Only not local fields are initialized to default values when not explicitly initialized. So, something like this
public class Main {
boolean flag;
void foo(){
System.out.println(flag);
}
}
compiles and foo() method would print false, while something like this
public class Main2 {
void foo(){
boolean flag;
System.out.println(flag);
}
}
wouldn't even compile. Furthermore, default value for a reference is null.
What you can do is designing your class in such a way that, when class is initialized, a value is assigne to its instance variables, something like
public class Main {
boolean flag;
{
flag=true;
}
void foo(){
System.out.println(flag);
}
}

Related

what is difference in "return name;" and "return this.name"

I am trying the Jacco testing and I am able to test the getStudentId from a class called Student which has:
public String getStudentId() {
return studentId;
}
When I try to test my other class named Product, I get an error - the only difference between the two is in the getX method. The getName method of Product is:
public String getName() {
return this.name;
}
and the error message says:
constructor Product in class Product cannot be applied to given types
The keyword this references the instance of the object you are currently in. Imagine having a class like this:
public class A {
private String property;
public void changeProperty(String property) {
this.property = property
}
}
Outside of the method the variable name property is not ambiguous and references the member variable of class A. But it is ambiguous inside the method changeProperty because there is also the argument named property.
How does Java resolves this conflict? If you just type property you will always reference the object with a smaller scope, so the argument of the method and not the member variable. By using this.property you can reference the member variable again.
If there is no such conflict in your object, like in your example, then you do not need the this statement and this.name is the same as name.
However as prevention of very nasty bugs one could always use this when referencing a member variable, just as good practice. Imagine you would create a method with such a name conflict in the future and forget about the member variable, whoops you easily create a bug that is hard to debug.
Some programmers even go further and do always give member variables other names than arguments, to prevent such name conflicts. For example member variables are often named:
mProperty or
_property
Note that the method this(...) references a constructor of the own object. It can be used in a constructor to pass the task to another constructor like:
public class A {
public A(String fileName) {
this(new File(fileName), true);
}
public A(File file) {
this(file, true);
}
public A(File file, boolean doSomething) {
// Code ...
}
}
Analogously there is also the keyword super which references the parent-class. For example:
public class A {
protected String property;
}
public class B extends A {
private String property;
public void foo() {
// Property of B
System.out.println(property);
// The same
System.out.println(this.property);
// Property of A
System.out.println(super.property);
}
}
This keyword can also be used to reference parent-constructor or other methods of the parent class.
So all in all it is just about resolving such name conflicts.
Now we know that, it is easy to see that the code you posted does not contain the bug.
When you use this.name you are using a attribute defined in your class, the attribute name. However, when you use only name, it could be any variable called so in your code, even the attribute. Example:
public String getName(){
String name = "Mery";
this.name = "Jacob";
return name;
}
This method return the value "Mery". If you put return this.name then you return the value "Jacob".
There's a chance you set studentID to a public variable. Anytime you are using this.whatever to return a variable from a getX function, the this. implies it's a private variable. More likely than not the studentID is public and that's why you got away with no 'this.' in front of it.

Variable to be initialized in a constructor with getter method

I am trying to learn Java by my self and i am making a game you all properly know, which is Monopoly.
I have searched for my answer but couldnt find it, so here it is.
I have a class Field with two variables fieldnumber and fieldname. My idea is to make a field with a number, so the program know where the players are (not relevant now).
The fieldname and fieldnumbershould only be readable (means not editable) after the program have created the fields and names for the fields.
I need to know how i can intialize these two variables into a contructor and make the variables to be only "getters", so they cant be changed later on.
(obs: the class Field is only a subclass, i need to use the data in the main class later on)
Im a bit confused and tried to read the book i am using, but no luck.
Declare the fields final, assign them in constructor and do not write setters.
Should the number of properties increase, you may consider using builder pattern to avoid constructor with many arguments.
class Field {
private final int fieldNumber;
private final String fieldName;
public Field(final int fieldNumber, final String fieldName) {
// you may validate the values here and throw exception in case of non-valid values
this.fieldNumber = fieldNumber;
this.fieldName = fieldName;
}
public int getFieldNumber() {
return fieldNumber;
}
public String getFieldName() {
return fieldName;
}
}
I suggest to make the two attribut as private (not accessible), initialize them when creating the instance, and you can use the getter to get their values:
class Field{
private String fieldname;
private int fieldnumber;
public Field (String fieldname, int fieldnumber)
{
this.fieldname = fieldname;
this.fieldnumber= fieldnumber;
}
public String getFieldname(){
return fieldname;
}
public int getFieldnumber(){
return fieldnumber;
}
public String toString(){
return fieldnumber+ " " +fieldname;
}
public boolean equals(Object obj){
Field field = (Field) obj;
return (fieldnumber == field.fieldnumber && fieldname.equals(field.fieldname);
}
}
A "getter" is a method that returns the value of your field.
A "setter" is a method typically taking one argument, setting the value of your field (possibly after some validation).
For good encapsulation, your instance fields should typically only be accessed within the maximum scope allowed within context (typically private fields with getters/setters, sometimes protected or package-protected fields when inheritance or more complex settings are required)
A field marked with the final non-access modifier can only be assigned once
In your case, if the fields are scoped within the instance of your class, but will never change once assigned, you can mark them final and assign them in a constructor or instance statement (no setters).
If they are not bound to an instance, but rather to the class, then you can mark them constant (static final) and assign them right away (you can then safely make them public if they are immutable - i.e. Strings or primitives)
Getter means a method that returns a value an object stores. A variable being a getter doesn't mean anything. Getters are usually used to get variables that are declared private; that is, variables that are not 'visible' from outside the class. See the example:
class Example {
private int value;
public Example(int valueToBeSet) {
this.value = valueToBeSet;
}
}
In the above example, the variable value is only visible from the class Example; any other class cannot get that variable. This is useful when you want that no other class is able to change its value. However, to get the value from the object, you use a getter:
class Example {
private int value;
public Example(int valueToBeSet) {
this.value = valueToBeSet;
}
public int getValue() {
return this.value;
}
}
Here the method getValue() is a getter. You cannot change the value, because it is private, but you can call the method getValue(), and get the value, because the method is public.
Other way to assign a variable's value, be able to get its value, but not be able to change it, is to use the final keyword:
class Example {
public final int value;
public Example(int valueToBeSet) {
this.value = valueToBeSet;
}
}
This way the variable's value can only be set once, in the constructor, and never again. However, you can still get the value from outside the class because it is public. This is often a good way to do things, however it has its downsides; namely as I explained, you cannot change the value anymore, and to get an object with a different value, you would have to create a new object altogether. This is the closest you can get to a "getter variable".

Can't use object variables without getter methods

I have an abstract class, AbstractNode, and a concrete class which extends it- Node.
I am trying to "program to an interface" by declaring objects of AbstractClass and instantiating them with new Node().
When I try to use the variables in Node after initializing them in the constructor, I get a Null Pointer. But everything works fine if I use a getter method instead. What am I missing?
public abstract class AbstractNode
{
String str;
public abstract String getStr();
}
public class Node extends AbstractNode
{
String str;
public Node()
{
str= new String();
}
public String getStr()
{
return str;
}
}
And the main method looks like this:
public static void main(String[] args)
{
AbstractNode n= new Node();
String nullStr= n.str;
String regularStr= n.getStr();
}
Now, nullStr contains a null reference, and regularStr contains a reference to n.str.
What is happening in here?
I can access other primitive type fields which do not require initialization, like int, directly without any getter methods.
You're "shadowing" the variable str. AbstractNode has a String named str, and then Node has a different String, also named str. The constructor for Node assigns an empty string to Node.str, but AbstractNode.str is still null because it's never been assigned. getStr() returns the value in Node.str because that's the "nearest" variable named str it sees. Your code in main is reading AbstractNode.str because the compiler is resolving its full name at compile time, and the declared type of the variable n is AbstractNode. Remove the duplicate String str in Node.
Now, nullStr contains a Null reference, and regularStr contains a reference to n.str. What is happening in here?
You've got two str variables - one declared in AbstractNode, and one declared in Node.
Now n is declared to be AbstractNode, so this:
String nullStr = n.str;
fetches the value of the variable declared in AbstractNode, whereas this:
String regularStr= n.getStr();
calls the method declared in Node, which returns the variable declared in Node.
Lessons you should learn:
Decide how many pieces of state an object should have, and only declare that many variables. Any time you have two variables with the same name in a class hierarchy, you should at least feel uncomfortable. If they genuinely represent different pieces of state, you should be able to find different names.
If you only have private fields, shadowing becomes mostly irrelevant, as you won't have direct access to the fields anyway.
I would suggest a fix of only declaring str in AbstractNode, ideally making it final, and making a protected constructor which accepts a value for it. You probably want to have an accessor to that in AbstractNode as well, although it's unclear. str isn't a descriptive name for the variable either - is it the value of the node? The name of the node? Who knows. My classes would be something like this:
public abstract class AbstractNode {
private final String name;
protected AbstractNode(String name) {
this.name = name;
}
public abstract String getName() {
return name;
}
// Presumably some abstract methods?
}
public final class Node extends AbstractNode {
public Node() {
super("Some default name");
}
}
The problem is that while methods are overridable, fields are not.
Because you declared the type of the variable as AbstractNode, the expression n.str references the field in AbstractNode, even though the actual type is Node. This is because fields are statically bound at compile time to the type.
Methods on the other hand are resolved at runtime, that's why you can override them: the expression n.getStr() is resolved based on the actual type of the object.
public String getStr()
{
return str;
}
and
String regularStr= n.getStr();
This function is overriden and at runtime the corresponding function in Node class is selected and hence you get appropriate results.
But when you say
String nullStr= n.str;
n variable from AbstractNode class is fetched(which is null).Note that Variables are read only and cannot be overriden,

Java :Setter Getter and constructor

I'm a bit confused about the use of getter/setters and constructors (see the below code for an example)
public class ExampleClass {
private int value = 0;
public ExampleClass () {
value = 0;
}
public ExampleClass (int i) {
this.value = i;
}
public int getValue() {
return value;
}
public void setValue(int val) {
this.value = val;
}
public static void main(String[] args) {
ExampleClass example = new ExampleClass (20);
example.setValue(20);
//Both lines above do same thing - why use constructor?
System.out.println(example.getvalue());
}
}
All I've learned is that we need getters/setters for security and that they can also be used to change or edit values later on.
My question is that if the constructor is the point of initialization and a default constructor is always present, why use a constructor with parameters to initialize values instead of getters/setters?. Wouldn't using the getter and setter provide security as well being able to easily change values at any stage. Please clarify this point for me.
default constructor is always there
Well actually its not always there. A default constructor is the one which is provided by the compiler (of course it is a no-arg constructor ) Only if there is no other constructor defined in the class
why we use constructor with parameters to initialize values instead of set get
Because there could be a condition that an object can always be created only when all the values are provided at the time of initialization itself and there is no default value. So all values must be provided otherwise code will not compile.
Consider this Book class
public class Book {
private String title;
private String author;
public Book(String title, String author){
this.title = title;
this.author = author;
}
//getters and setters here
}
Consider a condition where a book can be created only if it has title and author.
You cannot do new Book() because no-arg constructor is absent and compiler will not provide one because one constructor is already defined.
Also you cannot do new Book() because our condition does not meet as every book requires a title and author.
This is the condition where parameterized constructor is useful.
Sometimes, when creating a new object of a class, some values HAVE TO be provided. For an example, when connecting to database and creating Connection class object you have to provide a connection string, so that it knows what are you connecting to. Creating new connection without specyfing target database would be pretty useless, right?
Also, take a look at this
Foo foo=new Foo(1,2,3,4,5,6,7);
and this
Foo foo=new Foo();
foo.setP1(1);
foo.setP2(2);
foo.setP3(3);
foo.setP4(4);
foo.setP5(5);
foo.setP6(6);
foo.setP7(7);
First one looks better, right?
My question is that if constructor is point of initialization and
default constructor is always there so why we use constructor with
parameters to initialize values instead of set get.
If you think about an object transitioning into different states then it makes sense to have a parameterized constructor alongwith setters and getters. Let me try to put a real life scenario: Think about an Employee class, a new employee joins, you don't know many details but few and you create the object of Employee with defualt and base value of its attributes. You need to register the employee in the system and hence you used the parameterized constructor. Once you get more details about the employee, you use getters and setters to update the attributes.
this is purely upto your coding style. But IMO, I would use parametrized constructor:
to initialize those values which should not be changed. (like username parameter for a person object)
to initialize those values, without setting which, the object will be in invalid state.
Say, you are sending login parameters to a method. You can use in these to ways
Login obj = new Login();
obj.setUsername("user");
obj.setPassword("pw")// what if someone commented this out, or you forget to call it
and otherway,
Login obj = new Login("user", "pw");
while you can send Login object just after setting username in 1st case, it would be invalid at recieving end. but the second method is less prone to bugs, bcz it becomes necessary to pass all the required parameters.
Just to make it easier. It takes less code to use a constructor than to create an object and use the setters.
Sometimes you don't need to set all the fields to specific values at the time of creating. For examle, when you make an array. Also, as already said, it's safer when you use getters -- you can't get nullpointer.
Remember to write the default constructor when you've defined constructor with parameters. Or be sure not to use it.
First, both methods: Constructor and Setter are safe ways to change object's attributes. Are expected from Class author to expose or not safe ways to modify an instance.
The default constructor is always provided if you have not written one:
// Example of a Class with a Default Constructor
public class GetSet {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public static void main(String[] args) {
// Theres a implicit Default Constructor here
// Its ok to do that
// GetSet obj = new GetSet();
GetSet obj = new GetSet();
}
}
// Example of a Class without a Default Constructor
public class GetSet2 {
public GetSet2(String value) {
this.value = value;
}
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public static void main(String[] args) {
// GetSet2 obj = new GetSet2(); // compile time error
// Default constructor is not provided, since u wrote one
}
}
2. About which is better: Using a constructor or via setter, it depends on what u want. If you will only modify an attribute of a existing object, u may use the setter, or for a completely filled object you may prefer the constructor instead.
// Example of modifing an obj via Setter and Constructor
public class GetSet3 {
public GetSet3(String value1, String value2, String value3, String value4) {
this.value1 = value1;
this.value2 = value2;
this.value3 = value3;
this.value4 = value4;
}
private String value1;
private String value2;
private String value3;
private String value4;
// ... Getters and Setters
public static void main(String[] args) {
// Its easier to this
GetSet3 obj;
obj= new GetSet3("j", "a", "v", "a");
// instead that
// its also easy to forget or do something wrong
// when u have a lot of attributes to set
obj.setValue1("j");
obj.setValue2("a");
obj.setValue3("v");
obj.setValue4("a");
}
}
It's easier and safer to initialize your object variables via your constructor to avoid nullpointers.
If you instantiate your object without initializing your variables first and you do a get operation on one of your null variables, you might get a nullpointer exception at runtime because you forgot to manually set its value.
On the flipside of that, if you always initialize your object variables in your default constructor, you have a seriously reduced risk of getting nullpointer exceptions during runtime because none of your variables can be null unless you specifically set them via a setter (which is not recommended).
Constructor with arguments makes you get the object fully constructed. If you want to use default one, you will have to make sure the fields are set using setters. During set of some property, assume the exception is thrown, now you have an object which is not usable. In several cases, setter wouldn't be exposed but getters. In those cases, having constructor with arguments or a named constructor is the right option. In a nutshell, getters and setters do have their own importance rather than initializing the object.
Why use getters and setters?
Because you write it using less, more elegant and better readable code when you set the values as parameters in a constructor. Moreover, sometimes some fields are indispensable for the object, so a parameter constructor prevents the user from creating an object omitting necessary fields for the object's functionality. One is though not "oblidged" to call the setters.
To answer this question, I say by writing getters/setters, we create a provision to add any validation method in the future, currently, there is no validation, but if anything goes wrong in the future we just add validation logic in the setter.
we can also write the logic/validation in constructors but it's not a good practice. The constructor should be used only to initialize your object's state/fields. You should delegate the responsibility of other things to other methods.
Note that a constructor is called only once i.e, whenever you create a new object With a sufficiently large input, you can cause an exception in your constructor.
This is one of several reasons why you should not use a constructor to contain "business logic".

Immutability property in java

I know that when it comes to passing objects in java, the reference of object is passed as value. So what ever changes you make to that object is reflected in the original object as well. To avoid this we make use of immutability property in java.
So my question is, I have created an immutable class Employee, When I pass an object of this Employee class to some method in other class, I don't want that method to make any changes to this object. Even if it does, I don't want the changes to be affected to the original object created in the calling class.
Here is my sample code.
public final class Employee {
int employeeId;
public int getId() {
return employeeId;
}
public void setId(int id) {
this.employeeId = id;
}
}
public class Worker {
public static void process(Employee f, Employee g){
int c = f.getId();
f.setId(g.getId());
g.setId(c);
}
}
public class ImmutabilityTest{
public static void main(String[] args) {
Employee teamMember = new Employee();
Employee teamLead = new Employee();
teamMember.setId(5);
teamLead.setId(10);
System.out.println("Before process "+teamMember.getId() + " " + teamLead.getId());
Worker.process(teamMember, teamLead);
System.out.println("After process "+teamMember.getId() + " " + teamLead.getId());
}
}
The output will be
Before process 5 10
After process 10 5
Is there any way to avoid the change in the values of the member variables of the Employee class ? (apart from making them final)If not then how are we actually exploiting the Immutability property in java in user defined class ?
Any suggestions/opinions/pointers are appreciated ! Thanks..
Immutability is not a property in Java that can be applied to an Object with a single keyword, its a strategy that needs to be implemented on a case by case basis. Generally speaking, you utilize the final keyword and cloning in order to accomplish this. Note that the deeper your object nesting, the greater the level of difficulty in achieving true object immutability.
Here is a (more) immutable version of your Employee class:
public class Employee {
final int employeeId;
public Employee(final int id) {
super();
this.employeeId = id;
}
public int getId() {
return employeeId;
}
}
Note that reflection in Java makes it practically impossible to achieve true immutability, even with the use of the final instance variables and cloning.
Employee has a setter and has a non-private field, therefore it is not immutable.
Remove the setter, and make the field private, and your problem is solved.
Your other option is to pass a copy of the object (typically using a copy constructor to create it)
Applying the final keyword to a class simply indicates that the class can not be extended (or sub-classed).
It has nothing to do with whether or not its members can be modified.
You could change the visibility of the setId method to be package private, and make sure that Worker is in a different package to Employee.
Alternatively remove the setId method entirely.
[If the other class makes changes] I don't want the changes to be affected to the original object created in the calling class.
If you want to take that approach, then you need to create and pass a copy of the original object.
Note that unless you declare the private employeeId field to be final, you won't get the full benefit of immutability. Strictly speaking, the getId method needs to be synchronized if there is any possibility that different threads will call getId on the same Employee instance.
If you Don't want someone to change your properties value, you can keep them as private without setter.

Categories