We can create objects for the Student and initialize the variables of the object using the constructor. After that, we can no longer change the values the variables hold. The following statement would cause an error since we declared the variables to be private.

s1.name = “Ravi”;

The solution lies in providing public methods through which new values can be assigned to these variables and the values they hold can be accessed. These are commonly known as get and set methods. “Get methods” provides access to the value a variable holds while set methods assign values to the variables of the objects.

How to use get and set methods in Java

First, we shall see how we write a method. In order to set a variable to a new value, the method needs arguments similar to how the parametrized constructors required details such as rollNumber, name, and marks. The required arguments are specified in the method header within the parentheses by specifying the variable name and the data type for that variable name. The set method for the name looks as shown below:

public void setName ( String n ) {
name = n;
}

It is a convention to name the setter methods starting with the word ‘set’ followed by the variable name that is going to be set. If you wish to set the name for the first Student object s1 that you have created, use the following statement:

s1.setName(“Ravi”);

Now, we shall provide a get method for the variable name. As we have earlier said, methods can return value. These values can be of any primitive data type or reference type as a class. We will be returning the String here. It specifies the data type that is going to be returned in the method header instead of the word void. We have used the word void so far to show that the method does not return any value. The get method for the name would be:

public String getName() {
return name;
}

The value to be returned is specified by using the ‘return’ keyword. The variable or value that is to be returned follows the return keyword. We can specify not just a variable name but also a constant or an expression. The following return statements would also be equally fine.

return “XYZ”;

return “Name: “+name;

However, for the current scenario, we require that only the name be returned and not anything in addition. Also, the return statement should be the last line in a method that returns a value. Once the return statement is reached, it will not execute the lines of code that follow the return statement.

We cannot make any statements after the return statement. This is because the unreachable code generates compilation errors. Unreachable code refers to those statements which can never be executed. Consider the following get method for a name.

public String getName() {
return name;
name = “No name”;
}

The statement name=”No name” is an unreachable statement. This is because once the return statement is encountered, we will ignore the remaining lines of code in that method. Therefore, the above code produces compilation errors. However, in certain circumstances, we can provide a return statement and also write code following that statement when we use decision-making statements. We will look into it later on.

Now that we have written a get method, we shall see how we can use it. We can invoke the getName() method as a Student object, and we can store the returned value in a variable, can be printed on the screen, or can be used for any other purpose.

In the following statement, it stores the value returned by getName in the variable aName.

String aName = s2.getName();

As we have earlier initialized the name of the s2 object with “Sai”, aName will hold the value “Sai”. You can also directly print the returned value by invoking the method within the parentheses in the following way:

System.out.println (“Name of s2: “+ s2.getName() );

In a similar way, we can provide get and set methods for all other variables of the class. But what exactly is the use of these get and set methods? Instead of providing these methods, we could have simply made the variables public and we could access them in the following way instead of using get and set methods.

s1.name=”Ravi”;
System.out.println(“Name of s1: ” +s1.name);

Such a simpler approach would reduce the workload of providing a get and a set method for each of the five variables, reducing coding work. But that isn’t the preferred way for programmers. When data is easily accessible in that way, data isn’t secure.

One who uses the class can easily assign the marks1 of a Student with the integer 1000 where in reality, the maximum marks are 100. In order to restrict access and to check data before we assign it to the variables, we provided the get and set methods.

We have done a little checking for the name variable. We shall see what we can do for the marks1 variable. For this purpose, we use decision-making statements. We shall see two of them for now: the if statement and the if-else statement. The following is the syntax of the if statement:

if ( condition ) {
// code
}

Here is the syntax for if else statement

if ( condition ) {
// code1
} else {
// code2
}

We hope that you can guess what the purpose of the above statements is. To make sure that you’ve got it right, let’s look at them individually. If the condition stated in the parentheses of if the statement is true, then it executes the code in the block.

In a similar way, for the if-else statement, if the condition is true, it executes the first block of code. If the condition is false, it executes the statements in the else block. As already said, a block is a set of statements within a pair of curly braces.

They show ownership of a piece of code. Here, the blocks are used to show that the code in them is a part of the corresponding if or else statements. If the code which is to write for an if or else statement has just a single line or a single statement, there is no need to put the braces.

Another important thing is that variables declared within a block are not accessible outside the block. Here, if we declare a new variable ‘var’ in the if block and try to print its value in the else blocks, we will get a compilation error.

The same holds true for methods also. For instance, if we declare a new variable in the setName() method and try to access it in the getName() method, compilation errors would stop us. The following code is erroneous.

public void setName ( String n ) {
name = n;
int var = 34;
}

public String getName() {
var = 7; // incorrect var is not known here
return name;
}

Java get and set methods examples

Now, it’s time to see how these decision-making statements can enforce data validation in the set methods. But before that, we need to learn how we can write conditions in a language that is understandable by the computer. To make it short, we should be able to tell the computer ‘If marks are greater than or equal to zero and less than or equal to 100, assign the value to the variable marks, else set the marks to zero’.

In order to write conditions, we use relational and logical operators. We have already come across another category of operators – mathematical operators – and we have used them widely. Now, we shall see what the relational and logical operators are. Here are some operators in each of the categories that we would be used widely from now onwards.

Relationship operators:
> Greater than
< Less than
>= Greater than or equal to
<= less than or equal to
== equal to
!= not equal to
Logical operators
&& Logical and
|| Logical or
! Logical not

Relational operators are used to comparing the values of two data items – variables or constants. Each of the variables requires two operands, and the result returned would be true or false. These operators are like what we come across in mathematics; the only difference lies in their representation.

Look at the following code to see how these relational operators work. As already said, the result of a relational operation is a boolean value: true or false. Hence, we need a boolean variable to store the results.

int a=3, b=4, c=4;
boolean res1 = a>b ; // res1 holds false
boolean res2 = b<10; // res2 holds true
boolean res3 = b>=c; // res3 holds true
boolean res4 = c<=34; // res4 holds true
boolean res5 = b==c ; // res5 holds true
boolean res6 = 3!=a; // res6 holds true

Now, coming to logical operators – we have three of them. ‘Logical and’ and ‘logical or’ require two operands while ‘logical not’ require a single operand. The operands in all the cases are of type boolean, and the result got is also a boolean.

The ‘logical operator and’ (&&) returns true when both the operands are true, otherwise returns false. ‘Logical or’ (||) returns true when at least one operand is True. And last, ‘logical not’ (!) returns true if the operand is false and returns false if the operand is true. The following are the truth tables of these operators, while they are helpful in knowing the value of the returned boolean when the values of the operands are known.

Logical operator and &&
Operand 1 Operand 2 Result
true true true
true false false
false true false
false false false

Logical operator or ||
Operand 1 Operand 2 Result
true true true
true false true
false true true
false false false

Logical operator not !
Operand Result
true false
false true

The following code shows the use of logical operators:

boolean a = true;
boolean b = false;
boolean res1 = a&&b; // false
boolean res2 = a||b; //true
boolean res3 = !a; //false
boolean res4 = !false; // true
boolean res5 = true&&a; //true

Now, to frame the conditions that we would use in the if statements, we make combined use of the relational and logical operators. Operands for a logical operation can be expressions too. We frame these expressions using relational operators. For example, in order to check that the marks are both >= 0 and <= 100, we use the following conditions:

marks1 >= 0 && marks1 <=100

In the above expressions, the conditions marks1>=0 and marks1<=0 are evaluated first, and then the result is used to find the result of the ‘logical and’ operation. The order in which we do the operations depends on the precedence of operators. Relational operators have higher precedence than logical operators.

Hence, they are evaluated first. Further, the different relational and logical operators also have a precedence order among themselves. For a complete list of operator precedence, visit this page. When you are not sure about the precedence, use parentheses so it will test the expression in the way you would like. The above expression could have been written more clearly as:

(marks1 >= 0 ) && ( marks1 <=100)

The following is the complete setMarks1() method. This method takes an integer argument. If the argument satisfies the conditions, then marks1 is initialized to that argument, otherwise, we initialize marks1 to zero.

public void setMarks( int m) {
if ( m>=0 && m<=100 ) {
marks1 = m;
} else {
marks1 = 0;
}
}

We again emphasize the fact that Java is a free form of language. You can break a statement into two lines at any valid point and also write over one statement in one line. If you feel that reading the above code is inconvenient for you, we suggest the following alternative form.

public void setMarks( int m)
{
if ( m>=0 && m<=100 )
{
marks1 = m;
}
else
{
marks1 = 0;
}
}

Also, in this case, since the if and else blocks contain only a single statement, you can omit the braces and write the code in the following way:

public void setMarks( int m)
{
if ( m>=0 && m<=100 )
marks1 = m;
else
marks1 = 0;
}

Another rest regarding eth accessibility of a variable: Variables defined within a block are accessible in that block only. We know these conditions as the scope and lifetime of variables. Scope refers to the part of the code in which the variable is accessible, while lifetime refers to the duration for which the variable exits before it is destroyed by deallocating the memory allotted to it while declaring the variable.

If we declare a variable within the if block, the lifetime ends once we come off if the if block. Any attempt to access that variable would give an error that we do not define as the requested variable. If there is a need to declare variables inside such blocks and access them even after we move out of the blocks, then we need to declare these variables before the start of the block and outside the block. The following pieces of code show an incorrect way and a correct way of using such variables.

public void setMarks( int m)
{
if ( m>=0 && m<=100 )
int temp = m;
else
int temp = 0;
marks1 =temp; // Incorrect: temp is not known here
}
public void setMarks( int m)
{
int temp;
if ( m>=0 && m<=100 )
temp = m;
else
temp = 0;
marks1 =temp; // Correct: temp is known here
}

In the second piece of code, the variable temp is accessible since we declared it outside the if and else blocks in the same block as that of the method. Variables declared within we know methods as local variables. For example, here temp is a local variable. Such variables are accessible within that method only. The scope and lifetime of local variables is the method that blocks itself.

Now that we have learned how to use set and get methods to enforce the restriction on the data that can be assigned to a variable, we present a complete program below. We also provide a getAverage() method which computes the average of the Student. We use this getAverage() method in the printDetails() function.

Then we have a test class, where the object is initialized with values entered by the user. Then, we display the details of the student in two ways- one by using the printDetails() method and the other by using the get methods provided in the class.

Given below is the Student class

public class Student {

private int rollNumber;
private String name;
private int marks1;
private int marks2;
private int marks3;

public void setName(String s) {
name = s;
}

public String getName() {
return name;
}

public void setRollMumber(int r) {
if (r > 0) {
rollNumber = r;
} else {
rollNumber = 1;
}
}

public int getRollNumber() {
return rollNumber;
}

public void setMarks1(int m) {
if (m >= 0 && m <= 100) {
marks1 = m;
} else {
marks1 = 0;
}
}

public int getMarks1() {
return marks1;
}

public void setMarks2(int m) {
if ((m >= 0) && (m <= 100)) {
marks2 = m;
} else {
marks2 = 0;
}
}

public int getMarks2() {
return marks2;
}

public void setMarks3(int m) {
if ((m >= 0) && m <= 100) {
marks3 = m;
} else {
marks3 = 0;
}
}

public int getMarks3() {
return marks3;
}

public double getAverage() {
return (marks1+ marks2 + marks3) / 3.0;
}

public void printDetails() {
System.out.println(“Roll Number: ” + rollNumber);
System.out.println(“Name: ” + name);
System.out.println(“Marks in first subject: ” + marks1);
System.out.println(“Marks in second subject: ” + marks2);
System.out.println(“Marks in second subject: ” + marks3);
System.out.println(“Average: ” + getAverage());
}
}

Go through the above class carefully and note the following points. The condition expressions in each of the three methods for setting marks were written slightly differently. The parentheses used in them were redundant, i.e., it would have made no difference even if it omitted the parentheses. The following are the three different forms we have used. All of them are equivalent:

m >= 0 && m <= 100
(m >= 0) && (m <= 100)
(m >= 0) && m <= 100

We can also write the condition in the following way

m >= 0 && ( m <= 100)

Also, note how the if-else conditions were written. All the blocks have a single statement. Therefore, enclosing a single statement in curly braces is optional. Therefore, all three forms of if-else we have written for the different methods are equivalent. If you want to do so, you may also enclose another statement in curly braces and leave the if statement without a pair of curly braces.

Another thing is regarding the computation of averages. We need to write 3.0 and not 3. If we write it as 3, then the result will be an integer and the fractional part would be lost. We could also have written the statement as:

(marks1 + marks2 + marks3) / (double)3;

Note that the return keyword in getAverage() method is followed by the above expression and not a variable as in the other get method. Variables, constants, and expressions can be returned. Before returning the expression is first evaluated. You can also write the getAverage() method in the following way:

public double getAverage() {
double average =(marks1 + marks2 + marks3) / 3.0;
return average;
}

Also, note that the return type specified in the method header of the getAvearge() method is double. This type needs to match the data type of the value being returned.

The expressions have been written in different styles, using parentheses at some places, omitting them at a few other places, using curly braces at some points, and so on. This has been done to show that all the forms of coding are acceptable. However, when you write a program, use the same style throughout. It makes your program appeal to others.

Also, given below is the Test program. In this program, we use the second constructor that accepts a roll number and a name to create the object. We set the marks using different set marks methods. Then we print the data; first by invoking printDetails() method and then by using the different get methods.

The only thing worth mentioning here is the manner in which we have taken the input:

s1.setMarks1(s.nextInt());

This statement is correct. As already said, arguments passed are first tested before it passes them to the method. S.nextInt() method will be executed and then the integer will be passed to setMarks1() method.

The following is the StudentTest class.

import java.util.Scanner;

public class StudentTest {

public static void main(String[] args) {
Student student = new Student();
Scanner scanner = new Scanner(System.in);
System.out.print(“Enter Name: “);
String name = scanner.nextLine();
student.setName(name);
System.out.print(“Enter roll number: “);
int rollNumber = scanner.nextInt();
student.setRollMumber(rollNumber);
System.out.print(“Enter marks1: “);
int marks1 = scanner.nextInt();
student.setMarks1(marks1);
System.out.print(“Enter marks2: “);
int marks2 = scanner.nextInt();
student.setMarks1(marks2);
System.out.print(“Enter marks3: “);
int marks3 = scanner.nextInt();
student.setMarks1(marks3);
System.out.println();
System.out.println(“Printing details using printDetails() method: =”);
student.printDetails();
System.out.println();
System.out.println(“Printing details without using printDetails() method:”);
System.out.println(“Name: ” + student.getName());
System.out.println(“Roll Number: ” + student.getRollNumber());
System.out.println(“Marks1: ” + student.getMarks1());
System.out.println(“Marks2: ” + student.getMarks2());
System.out.println(“Marks3: ” + student.getMarks3());
System.out.println(“Average: ” + student.getAverage());
}
}

We have named the Student object as a student. You can give any name, including the same name as that of the class, capitalization included. For instance, the following statement is also correct.

Student Student = new Student();

Here is a sample input where the user enters all the correct details.

Enter name: Sai
Enter roll number: 34
Enter marks1: 98
Enter marks2: 97
Enter marks3: 100

Printing details using printDetails() method:
Roll Number: 34
Name: Sai
Marks in first subject: 98
Marks in second subject: 97
Marks in second subject: 100
Average: 98.33333333333333

Printing details without using printDetails() method:
Name: Sai
Roll Number: 34
Marks1: 98
Marks2: 97
Marks3: 100
Average: 98.33333333333333

Here is a sample input where the user enters incorrect details.

Enter name: Sai
Enter roll number: 34
Enter marks1: 100
Enter marks2: -34
Enter marks3: 347

Printing details using printDetails() method:
Roll Number: 34
Name: Sai
Marks in first subject: 100
Marks in second subject: 0
Marks in second subject: 0
Average: 33.333333333333336

Printing details without using printDetails() method:
Name: Sai
Roll Number: 34
Marks1: 100
Marks2: 0
Marks3: 0
Average: 33.333333333333336

Now, try creating a Student object using the constructor where all the values are all passed in the following way.

Student s = new Student ( “sai”,34,100,-34,347);

Now invoke the printDetails() method. You see that marks2 and marks3 were not set as zero but as -34 and 347. The reason is that in the constructor; we have not provided data validation. We have directly assigned the values. Hence, we need to change the constructors and call the set method from the constructors instead of directly assigning the values.

The following is a changed version of the constructor. The name variable can be either directly initialized or by calling the set method. Either way, it gives the same result because no data validation was provided for the name variable. The following is a changed version of the constructor.

public Student(String n, int rn, int m1, int m2, int m3) {
name = n;    setRollNumber(rn);
setMarks1(m1);
setMarks2(m2);
setMarks3(m3);
}