2

This may sound silly, but I am wondering, when we declare a class attributes in a class, must that class attribute be in the constructor, or do we only put it in the constructor when we want to initialize it?

For example, can I do this?

Public class A {
    private int n;
    private string name;
    
    public A(int n) { 
        this.n = n;
    }
}

Notice that I did not put class attribute "name" in the constructor, will that cause the system to throw exception? If so, will it throw NoPointerException if I'm using "name" in one of my following methods created under class A?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Rey Cai
  • 35
  • 5
  • 1
    You should try it out. There is nothing says that all of the attributes have to be in the constructor. It's fine and name will be initialized to null. – matt Aug 27 '21 at 15:42
  • 1
    If "name" is null and you try to call an instance method on it of course it'll throw an NPE. That's a different question than if you must initialize it in the ctor: you can initialize it wherever and however you want, with the caveat that relying on the class user to do the right thing is fraught. – Dave Newton Aug 27 '21 at 15:44

2 Answers2

3

About not assigning a value to a field in a constructor: yes you can do that, but in general should try and avoid null values especially if having a null valued field puts your object instance in an invalid or undefined state.

If you just return the field using a "getter": getName(): String then it won't throw a NullPointerException: that will only be thrown when you e.g. try and call String methods using name. It may also be that a method that you call will throw an exception if one of the parameters evaluates to null.

If you decide to return name while it may still be null then you should probably return an Optional<String> instead.

If you mark the field final then you do need to assign it, but it also means that you cannot change the reference thereafter. If you want to force assignment then you could annotate using @NonNull or similar.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
3

Constructors do not have to explicitly initialize every attribute. As comments above indicate, default values will be used. Choosing what to do in constructors is a design choice.

You can force all attributes to have good initial values by making them arguments of the constructor(s). This has the advantage that you cannot create a "bad" object. It has the disadvantage that constructors need arguments for every attribute, which makes it difficult to add new attributes.

Your constructor can accept the Java default for attributes that are not explicitly given, or your constructor can set the attribute to your own default value.

You can also have multiple constructors with different parameters.

In some situations you must include a no-argument constructor. This is true when using certain frameworks that expect your class to behave like Java-beans. If that means nothing, don't worry about it for now.

So you could define your class as shown below. Obviously, you will want to define more methods, like getters and setters, but these are not shown for simplicity.

public class A
{
    private int n;

    private String name;
    
    public A ()
    {
        n = 42;
        name = "na";
    }

    public A (int n)
    {
        this.n = n;
        // name will be null
    }

    public A (int n, String name)
    {
        this.n = n;
        this.name = name;
    }
}
Christopher
  • 411
  • 3
  • 7
  • Thank u for ur reply, i see what it is now. – Rey Cai Aug 27 '21 at 16:26
  • *"This has the advantage that you cannot create a "bad" object."* - Not entirely true. What if the caller passes a `null` for an argument that shouldn't be `null`? If the constructor doesn't validate the argument, then you have created a "bad object" ... just as much as if your attribute was default initialized to `null`. – Stephen C Aug 28 '21 at 12:29
  • If null arguments are a problem the constructor can throw an Error or Exception instead of allowing the "bad" object to be created. – Christopher Aug 28 '21 at 14:02