getCause() is used for chained exceptions, where you have one wrapped inside another - it represents the exception that was the underlying cause. In this case there is no underlying cause, so it correctly returns null.
What would you want it to return? If you want a description of what has gone wrong, that's what the message is for.
Your Exception has the cause as null. Hence it is printing null. Notice the constructor in the Throwable interface class that takes a Throwable and the one that takes a message and a Throwable. If you do not construct your Exception object by passing it a Throwable argument, the cause will be null.
getCause method is generally helpful when you wrap one exception into another. Like for example-
The calling code can have
This should now print something like
Exception1 : and the reason is null.
If you want the message also, in the constructor parameters, you need to provide both - the message ( String ) and the Throwable and need to pass both of them as parameter while throwing the new Exception.
However, it is not advisable to wrap one exception into another unless there is a good reason to do so.
Note that you can also make use of the initCause method but for your case I don't think that is necessary.