1

I have the following class.

class Student(id: String, name: String) { var id: String? = null var name: String? = null var grade: String? = null constructor(id: String, name: String, grade: String) : this(id,name) { this.grade = grade } } 

Use:

 var student = Student("AB001","Smith","N/A") prinln(student.id + student.name + student.grade) 

Output:

nullnullN/A

Can anyone explains why I get the output null from default constructor?

3 Answers 3

5
class Student { var id: String? = null var name: String? = null var grade: String? = null constructor(id: String, name: String) { this.id=id this.name=name } constructor(id: String, name: String, grade: String) : this(id, name) { this.grade = grade } } 

or

class Student(var id: String?, var name: String?) { var grade: String? = null constructor(id: String, name: String, grade: String) : this(id, name) { this.grade = grade } } 
Sign up to request clarification or add additional context in comments.

Comments

4

Besides the other answers, there's another way. Initialize the properties directly using the primary constructor parameters:

class Student(id: String, name: String) { var id: String? = id var name: String? = name var grade: String? = null constructor(id: String, name: String, grade: String) : this(id,name) { this.grade = grade } } 

Note, since id and name are always initialized with a non-nullable value, you can omit the ?. Apart from that, you can omit the secondary constructor using a default value in the primary constructor:

class Student(id: String, name: String, grade: String? = null) { var id: String = id var name: String = name var grade: String? = grade } 

But now we only have one constructor left, so we can pull the properties directly into the constructor:

class Student( var id: String, var name: String, var grade: String? = null ) 

Because the body of the class is now empty, I also omitted the curly braces.

1 Comment

Btw, are you sure, you need to declare the properties as vars? If you won't change them later, make them vals.
1

Or

class Student(id: String, name: String) { var id: String? = null var name: String? = null var grade: String? = null init { this.id = id this.name = name } constructor(id: String, name: String, grade: String) : this(id,name) { this.grade = grade } } 

The init block is how you use parameters in the primary constructor, which must be done when they're not marked as vals or vars there.

Said differently, since you didn't mark the parameters in your primary constructor (the parenthesis right next to the class name) as vals or vars, they weren't automatically assigned as properties. In order to use parameters in the primary constructor, especially those that don't get marked as vars and vals, you need an init block.

I can't help but think that what you truly want is this though:

class Student (var id: String, var name: String, var grade: String? = null) 

Maybe even changing them to vals instead of vars.

2 Comments

By the way, when does this init block executed? After the constructor executed?
Yes. The code is executed in the order, it appears. Because the secondary constructor calls the primary constructor, it first get's executed, then the properties are initialized to null, then the init block runs and finally the code inside the secondary constructor runs.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.