-3

Given these baby classes

public class Domain<V> {
    public Domain(V v) {} // (1)
    public Domain() {}    // (2)
}

and

public class User {}

and a client

public class App {
    public static void main( String[] args )
    {
        Domain<User> d1 = new Domain<>(new User());
        Domain<User> d2 = new Domain<>(null);
    }
}

Which constructor is it going to hit, (1) or (2)?

Spoiler: its one

What's the story behind that? It implies, that null is while effectively nothing, still an argument or what?

Progman
  • 16,827
  • 6
  • 33
  • 48
TMOTTM
  • 3,286
  • 6
  • 32
  • 63
  • 2
    Add some print info and check for yourself. – Romain Hippeau Jun 23 '23 at 12:19
  • I can see where its going, but I dont understand why. It's essentially matching `null` to `V`, which surprises me. Is that's what is happening? – TMOTTM Jun 23 '23 at 12:26
  • 1
    `null` is something. It is the empty value of a reference type. What if you did this. `User nu = null;` Then you called 'new Domain<>(nu);` which one would you expect it to call? When you call `new Domain<>(null);` it will use a constructor with a single argument. It doesn't know what null is so it needs other information to interpret. – matt Jun 23 '23 at 12:49

1 Answers1

1

To make it more intuitive, try to look at it this way:

public class App {
    public static void main(String[] args) {
        User user = getUserFromSomewhere(); // This potentially returns null!
        Domain<User> d1 = new Domain<>(user);
        Domain<User> d2 = new Domain<>(null);
    }
}

Doesn't matter if the user is actually null or not (let's imagine we don't know it), for Java, it will always mean to run the constructor (1), because null is still a value, even though it semantically means 'nothing'. You can imagine this as passing a an integer 0 to some function.

Besides, your constructor could potentially have logic like this:

public class Domain<V> {
    public Domain(V v) {
        if (v == null)
            System.out.println("Hello");
        else
            System.out.println("World");
    }
    public Domain() {} 
}

If Java were to run the second constructor instead, you wouldn't be able to use such logic.

David
  • 161
  • 2
  • 6
  • 2
    The important thing to me is `null is still a value`. – TMOTTM Jun 23 '23 at 12:28
  • Yes `null` is a valid value and compiler matches up the method by arguments, otherwise you are implying that JVM should make a runtime choice between `someMethod(a,b,c)` and `someMethod(b)` based on checking the passed in values - and what do you call if a/b/c were all null? – DuncG Jun 23 '23 at 12:47