0% found this document useful (0 votes)
31 views16 pages

Java Getter and Setter Methods Guide

java tutorial
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views16 pages

Java Getter and Setter Methods Guide

java tutorial
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Getter and Setter Method in Java

Example
Getter and setter methods are frequently used in Java programming. Getter and setter
methods in Java are widely used to access and manipulate the values of class fields.
Usually, class fields are decorated with a private access specifier. Thus, to access them,
public access specifiers are used with the getter and setter methods.

The Need of Getter and Setter Method


One may argue that declare the class fields as public and remove the getter and setter
methods. However, such a coding style is bad, and one may put some absurd value on
the class fields. Let's understand it with the help of an example.

1. public class GetterSetterExample


2. {
3. public salary;
4.
5. public storeSalaryDB(int salary)
6. {
7. // code for storing the salary in the database
8. }
9.
10. // main method
11. public static void main(String argvs[])
12. {
13. GetterSetterExample obj = new GetterSetterExample();
14.
15. [Link] = -50000;
16.
17. // storing salary in database
18. [Link](salary);
19.
20. }
21. }

Observe that the code is storing a negative salary in the database that is wrong. An
organization never credits a negative salary to the account of an employee. Assigning an
absurd amount to the salary variable happened because it is declared with a public
access specifier. The correct way to write the above code is:

1. public class GetterSetterExample


2. {
3. private salary;
4.
5. // a setter method that assign a
6. // value to the salary variable
7. void setSalary(int s)
8. {
9. if(s < 0 )
10. {
11. s = -s;
12. }
13.
14. [Link] = s;
15. }
16.
17.
18. // a getter mehtod to retrieve
19. // the salary
20. int getSalary()
21. {
22. return [Link];
23. }
24.
25. public storeSalaryDB(int salary)
26. {
27. // code for storing the salary in the database
28. [Link]("The ")
29. }
30.
31. // main method
32. public static void main(String argvs[])
33. {
34. // creating an object of the class GetterSetterExample
35. GetterSetterExample obj = new GetterSetterExample();
36.
37. [Link](-50000);
38.
39. int salary = [Link]();
40.
41. // storing salary in database
42. [Link](salary);
43.
44. }
45. }

Now, we can see better control over what we send to the database to store. Whenever
the salary is negative, we are converting the salary into a positive value, and then we are
sending it to the database to store. Thus, no matter what value we send to the setter
method, the if-block of the setter method takes care of the absurd value and thus gives
better control on the salary value.

Getter Setter Java Program


FileName: [Link]

1. class Employee
2. {
3. // class member variable
4. private int eId;
5. private String eName;
6. private String eDesignation;
7. private String eCompany;
8.
9. public int getEmpId()
10. {
11. return eId;
12. }
13. public void setEmpId(final int eId)
14. {
15. [Link] = eId;
16. }
17. public String getEmpName()
18. {
19. return eName;
20. }
21. public void setEmpName(final String eName)
22. {
23. // Validating the employee's name and
24. // throwing an exception if the name is null or its length is less than or equal to 0.
25. if(eName == null || [Link]() <= 0)
26. {
27. throw new IllegalArgumentException();
28. }
29. [Link] = eName;
30. }
31. public String getEmpDesignation()
32. {
33. return eDesignation;
34. }
35. public void setEmpDesignation(final String eDesignation)
36. {
37. [Link] = eDesignation;
38. }
39. public String getEmpCompany()
40. {
41. return eCompany;
42. }
43.
44. public void setEmpCompany(final String eCompany)
45. {
46. [Link] = eCompany;
47. }
48. // for printing the values
49. @Override
50. public String toString()
51. {
52. String str = "Employee: [id = " + getEmpId() + ", name = " + getEmpName() + ", de
signation = " + getEmpDesignation() + ", company = " + getEmpCompany() + "]";
53. return str;
54. }
55. }
56. // Main class.
57. public class GetterSetterExample1
58. {
59. // main method
60. public static void main(String argvs[])
61. {
62. // Creating an object of the Employee class
63. final Employee emp = new Employee();
64.
65. // the employee details are getting set using the setter methods.
66. [Link](107);
67. [Link]("Kathy");
68. [Link]("Software Tester");
69. [Link]("XYZ Corporation");
70.
71. // Displaying the details of the employee details using the
72. // 'toString()' method, which uses the getter methods
73. [Link]([Link]());
74. }
75. }
Output:

Employee: [id = 107, name = Kathy, designation = Software Tester, company =


XYZ Corporation]

Bad Practices in Getter and Setter Methods


There are some common bad practices that people usually do when they deal with the
getter and setter methods.

Bad Practice 1:
Using getter and setter for the variable that is declared with low restricted scope.

1. public salary;
2.
3. void setSalary(int s)
4. {
5. salary = s;
6. }
7.
8. int getSalary()
9. {
10. return salary;
11. }

It is evident that from the main method, one can directly access the variable salary,
which is not only bad but also makes the presence of the getter and setter methods
irrelevant.

Bad Practice 2:
Using an object reference in the setter method. Consider the following program.

FileName: [Link]

1. class ABC
2. {
3. private int[] val;
4.
5. void setVal(int[] arr)
6. {
7. [Link] = arr; // line 7
8. }
9.
10. // for displaying the value
11. // present in the val array
12. void display()
13. {
14. int size = ([Link]).length;
15.
16. for(int i = 0; i < size; i++)
17. {
18. [Link]([Link][i] + " ");
19. }
20.
21. }
22.
23. }
24.
25. // Main class
26. public class GetterSetterExample2
27. {
28. // main method
29. public static void main(String argvs[])
30. {
31. // instantiating the class ABC
32. ABC obj = new ABC();
33.
34. int mainArr[] = {3, 4, 6, 8, 78, 9};
35.
36. // invoking the setter method
37. [Link](mainArr);
38.
39. // invoking the display method
40. [Link]();
41.
42. // updating the value at the 0th index
43. mainArr[0] = -1;
44.
45. [Link]();
46.
47. [Link]();
48. }
49. }

Output:

3 4 6 8 78 9
-1 4 6 8 78 9

Explanation:

References are a bit tricky to deal with! In the above code, at line 43, the value got
updated at the 0th index for array mainArr[]. However, it also got reflected in the array
val[]. It should not happen as val[] array is declared private; hence, it is expected that any
code outside of the class ABC should not modify it. However, because of the references,
everything is messed up. The setter method setVal() expecting a reference of an int
array, and at line 7, the reference of the int arr[] is getting copied to val[]. Note that the
reference variable arr[] is storing the reference of the array mainArr[]. Thus, we can say
val[] is storing the reference of the mainArr[].

Therefore, whatever we change in the mainArr[] also gets reflected in the val[] array,
which violates the purpose of the setter method. Also, there is no meaning in adding the
private access specifier to the val[] array; because one can change the value of the val[]
array in the main method, which is evident by looking at the output.

A better way of writing the above code is:

FileName: [Link]
1. class ABC
2. {
3. private int[] val;
4.
5. void setVal(int[] arr)
6. {
7. int size = [Link];
8.
9. // allocating the memory as
10. // per the array arr size
11. val = new int[size]; // line 11
12.
13. for(int i = 0; i < size; i++)
14. {
15. // copying the value one by one
16. // into the val array
17. [Link][i] = arr[i]; // line 17
18. }
19. }
20.
21. // for displaying the value
22. // present in the val array
23. void display()
24. {
25. int size = ([Link]).length;
26.
27. for(int i = 0; i < size; i++)
28. {
29. [Link]([Link][i] + " ");
30. }
31.
32. }
33.
34. }
35. // Main class.
36. public class GetterSetterExample3
37. {
38. // main method
39. public static void main(String argvs[])
40. {
41. // instantiating the class ABC
42. ABC obj = new ABC();
43.
44. int mainArr[] = {3, 4, 6, 8, 78, 9};
45.
46. // invoking the setter method
47. [Link](mainArr);
48.
49. // invoking the display method
50. [Link]();
51.
52. // updating the value at the 0th index
53. mainArr[0] = -1; // line 53
54.
55. [Link]();
56.
57. // invoking the display method again
58. [Link]();
59.
60. }
61. }

Output:

3 4 6 8 78 9
3 4 6 8 78 9

Explanation:
In the above code, we are doing the deep copy of elements of the array arr[]. In line 11,
we are creating an entirely new array. Thus, the val[] is not referring to the arr[]. Also, in
line 17, only values of the element are getting copied. Therefore, when we change the
value of the 0th element at line 53, the change is not reflected in the val[]. Thus, the
above code respects the encapsulation of the private member variable val[].

Bad Practice 3:
Returning an object reference in the getter method. Observe the following program.

FileName: [Link]

1. class ABC
2. {
3. private int[] val = {67, 43, 68, 112, 70, 12};
4.
5. // the getter method
6. public int[] getVal()
7. {
8. // returning the reference
9. return val; // line 9
10. }
11.
12. // for displaying the value
13. // present in the val array
14. void display()
15. {
16. int size = ([Link]).length;
17.
18. for(int i = 0; i < size; i++)
19. {
20. [Link]([Link][i] + " ");
21. }
22.
23. }
24.
25. }
26. // Main class.
27. public class GetterSetterExample4
28. {
29. // main method
30. public static void main(String argvs[])
31. {
32. // instantiating the class ABC
33. ABC obj = new ABC();
34.
35. // invoking the getter method
36. // and storing the result
37. int arr[] = [Link]();
38.
39. // invoking the display method
40. [Link]();
41.
42. // updating the value at the 0th index
43. arr[0] = -1; // line 42
44.
45. [Link]();
46.
47. // invoking the display method again
48. [Link]();
49.
50. }
51. }

Output:

67 43 68 112 70 12
-1 43 68 112 70 12

Explanation:
The above code is not handling the references properly. The getter method is returning
the reference of the array. The arr[] is storing the reference of the array val[], which is
declared private in the class ABC. Because of exposing the reference to the outer world,
arr[] can manipulate the val[], and thus, the encapsulation of the class ABC is breached.
The proper way to handle the above is:

FileName: [Link]

1. class ABC
2. {
3. private int[] val = {67, 43, 68, 112, 70, 12};
4.
5. // the getter method
6. public int[] getVal()
7. {
8.
9. int size = [Link];
10.
11. // creating a new array
12. int temp[] = new int[size];
13.
14. // copying the content of the array to temp array
15. for(int i = 0; i < size; i++)
16. {
17. temp[i] = val[i];
18. }
19.
20. return temp;
21. }
22.
23. // for displaying the value
24. // present in the val array
25. void display()
26. {
27. int size = ([Link]).length;
28.
29. for(int i = 0; i < size; i++)
30. {
31. [Link]([Link][i] + " ");
32. }
33.
34. }
35.
36. }
37. // Main class.
38. public class GetterSetterExample5
39. {
40. // main method
41. public static void main(String argvs[])
42. {
43. // instantiating the class ABC
44. ABC obj = new ABC();
45.
46. // invoking the getter method
47. // and storing the result
48. int arr[] = [Link]();
49. // invoking the display method
50. [Link]();
51. // updating the value at the 0th index
52. arr[0] = -1; // line 54
53. [Link]();
54. [Link]();
55. }
56. }

Output:

67 43 68 112 70 12
67 43 68 112 70 12
Explanation: In the above code, the reference of the private array is not sent to the
outside world. In the getter method, a new array is created whose reference is sent to
the main method. Therefore, when the value at the 0th index gets changed at line 54,
that change impacts the temp[] array, not the private array val[]. Thus, the encapsulation
of the class ABC is maintained, as the reference of the array val[] is not exposed to the
outside world.

Note 1: For primitive data types (int, char, etc.), one does not need to create a copy in the
getter and setter methods, as the concept of references is absent for the primitive data
types.

Note 2: Strings object types also work on the references. However, unlike the above
examples, one does not need to take care of the String references exposed to the outside
world. It is because Strings are immutable. Thus, when one manipulates the string in the
main method (or anywhere else), a new String object is created, and the previous one
remains untouched.

FileName: [Link]

1. class ABC
2. {
3. private String str = null;
4.
5. // a setter method
6. void setVal(String s)
7. {
8. // reference is getting copied
9. [Link] = s;
10. }
11.
12. // for displaying the string
13. void display()
14. {
15. [Link]( "The String is: " + [Link]);
16. }
17. }
18.
19. // Main class.
20. public class GetterSetterExample6
21. {
22. // main method
23. public static void main(String argvs[])
24. {
25. // creating an object of the class ABC
26. ABC obj = new ABC();
27.
28.
29. // input string
30. String inputStr = "Hello India!";
31.
32. // invoking the setter method
33. [Link](inputStr);
34.
35. [Link]();
36.
37. // manipulation is not allowed!
38. // it leads to the creation of the new string
39. inputStr = "Hello World!";
40.
41. [Link]();
42.
43. }
44. }

Output:

The String is: Hello India!


The String is: Hello India!

Common questions

Powered by AI

Deep and shallow copies significantly affect object integrity and encapsulation in Java. A shallow copy involves copying references to the same memory location, leading to unintended modifications outside of the class, as shown in Source 3 where changes to an array outside reflected inside due to shared references. Deep copies, however, create entirely new instances, preserving the private state and maintaining encapsulation. In Source 4, by copying array contents one by one, deep copying prevents external modifications to the object's state, which is crucial for maintaining encapsulation and object integrity .

A situation where encapsulation is violated using setter methods is when an object reference is directly assigned to a private field. For example, if a setter method assigns an array reference to a private array field, changes to the original array affect the private field. In Source 3, the array reference passed to the setter method setVal() allowed external updates to the internal array due to shared references, compromising encapsulation . The corrected approach involves creating a deep copy of the array within the setter method .

Improper handling of array references in getter methods can lead to security vulnerabilities, as it allows external code to modify private data. When a getter method returns a reference to an internal array, any changes made to that array outside the class affect the internal state, violating encapsulation. This may lead to data corruption and unpredictable behavior, as demonstrated in Source 5, where changes to an externally referenced array impacted the internal state . Such vulnerabilities can be mitigated by returning a new array copy from the getter method, ensuring external modifications don't affect the internal data.

Preventing reference-based encapsulation breaches includes copying references for mutable objects. One effective strategy is deep copying, where a new instance with copied values is provided rather than exposing internal references directly, as demonstrated when array references were deep copied to avoid unintended modifications . Additionally, returning read-only views or immutable wrapper objects instead of raw data can further protect internal state integrity. Using immutable objects where possible, like Strings, inherently guards against reference-based issues, as they cannot be modified externally .

Returning a reference of a mutable object from a getter method is bad practice because it breaks encapsulation by exposing the object's internal state, allowing external modifications. As illustrated in Source 5, when an array's reference was returned directly, external changes could alter private data. This practice can be improved by returning a copy of the mutable object, such as creating a new array with the same content as the original array, preventing outside code from altering internal data and ensuring data integrity is maintained .

Encapsulation is a key principle of object-oriented programming that concerns containing fields within a class and restricting access to them. Getter and setter methods are used to implement encapsulation by allowing controlled access and modification of private fields. They maintain data integrity by checking values before setting fields and ensure the internal state of the object remains consistent . Without encapsulation, as demonstrated in the example where the salary was directly set to a negative value, there is a risk of introducing invalid states to the objects .

Immutable objects, such as Strings, alleviate problems with object references because their state cannot be changed after creation. This immutability ensures that even if a String reference is shared outside a class, external changes don't affect the original object. For example, when a String is modified, a new instance is created rather than altering the existing one, preserving encapsulation and integrity . This behavior simplifies management of object references and reduces the risk of unintended modifications, a common issue with mutable objects.

Using public access specifiers directly on fields can lead to poor software maintenance and reduced robustness, as it exposes internal state and allows unrestricted modification, as seen in the negative salary example where invalid data was set . In contrast, getter and setter methods encapsulate field access and provide a controlled mechanism to modify and retrieve data, allowing for validation and integrity checks, enhancing maintainability and robustness. They enable developers to make changes internally without affecting external code, supporting cleaner and more adaptable software .

Getter and setter methods in Java provide controlled access to class fields, allowing for validation and encapsulation. Directly accessing fields, such as declaring them with public access specifiers, can lead to issues like invalid data being assigned, as seen with the salary example where a negative value was stored . Getter and setter methods prevent this by applying checks and maintaining a level of abstraction that enhances code maintainability and security.

Primitive data types in Java do not suffer from reference issues because they hold values directly rather than memory addresses pointing to additional data. Unlike object types, such as arrays and Strings, primitives aren't susceptible to reference manipulation breaches. Getters and setters for primitives work straightforwardly, as they transfer copies of the actual data value. This inherent simplicity and directness don't require defensive copying techniques inherent to object types, whose reference-based design requires careful handling to maintain encapsulation .

You might also like