Murad Axundov
Murad Axundov

Reputation: 59

Why can't I declare object in my local class in Java?

I started learning programming recently. I know it can look meaningless, but I want to know reason why I can't declare my object in my local class. I can declare it on the second class that I create, but can't declare in the main one.

Here is my code :

public class User {
    
 public String name;
 public String surname;
 public int age;
 public static String companyname;
 
 User student = new User();
 student.name = "Jack";
}

Upvotes: 0

Views: 197

Answers (1)

dani-vta
dani-vta

Reputation: 6830

First of all, I want to open my answer by saying that you cannot recursively declare an instance of User within your User class as this will overflow the stack when a new User is created. In fact, the creation of a User would trigger the creation of another one which in turn would generate another User and so forth causing an endless chain of User instantiation. This is a logical error.

Also, your IDE is probably signaling you another error, a syntax one, about the statement:

student.name = "Jack";

Although logically incorrect, you are grammatically allowed to declare a User within your User class, as you're doing here

User student = new User();

This will be interpreted as an attribute of your User class. However, you cannot write any logic outside a block. If you want to assign the name "Jack" to your student variable you have three options:

  1. Define a constructor which accepts a name and pass the value Jack to your student instance during its instantiation.
public class User {

    public String name;
    public String surname;
    public int age;
    public static String companyname;

    //Let's pretend this is fine
    User student = new User("Jack");
    
    public User(String name){
        this.name = name;
    }
}
  1. Include your statement within an instance block.
public class User {

    public String name;
    public String surname;
    public int age;
    public static String companyname;

    //Let's pretend this is fine
    User student = new User();

    {
        student.name = "Jack";
    }
}
  1. Initialize your student field inside the class constructor.
public class User {

    public String name;
    public String surname;
    public int age;
    public static String companyname;

    //Let's pretend this is fine
    User student = new User();

    public User(){
        this.student.name = "Jack";
    }
}

However, all these options have little meaning and they were all meant to let you understand the contexts where you can write your statement.

I'm assuming that you simply wanted to define a User with its actual fields (name, surname, age and companyname) and then declare a Student in a "testing" context, like a main method, to test your class. This is most likely what you were attempting to do:

public class User {

    public String name;
    public String surname;
    public int age;
    
    public static String companyname;

    public User(String name, String surname, int age) {
        this.name = name;
        this.surname = surname;
        this.age = age;
    }

    public static void main(String[] args) {
        User student = new User("Jack", "Black", 15);
    }
}

On a side note, you should define a class' attributes (its fields) as private. The public access modifier is generally meant for the services offered by an object (its methods). This is also known as information hiding or encapsulation. Basically, you want to hide the internal implementation of your class and protect its state (its fields) from any abuse, like assigning inconsistent values. Your methods are the "outer layer" to regulate the access to your internal state, they contain the logic to prevent misuses and inconsistent changes to the object's state.

No Encapsulation

public class User {

    public String name;
    public String surname;
    public int age;
   
    public User(String name, String surname, int age) {
        this.name = name;
        this.surname = surname;
        this.age = age;
    }

    public static void main(String[] args) {
        User student = new User("Jack", "Black", 15);
        
        //misuse of the object's attributes
        student.age = -20;
    }
}

Encapsulation

public class User {

    private String name;
    private String surname;
    private int age;

    public User(String name, String surname, int age) {
        this.name = name;
        this.surname = surname;
        this.age = age;
    }

    public void setAge(int age) {
        if (age < 0 || age > 120) {
            return;
        }
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public static void main(String[] args) {
        User student = new User("Jack", "Black", 15);

        student.age = -20; //gives you an error, you cannot access anymore this field directly

        student.setAge(-20); //It won't update its age to -20
        System.out.println(student.getAge()); //It still prints 15

        student.setAge(25); //Regulates the update and allows the assignment
        System.out.println(student.getAge()); //Prints 25
    }
}

This article explains quite well the concept of encapsulation:

https://www.geeksforgeeks.org/encapsulation-in-java/

Upvotes: 1

Related Questions