I am writing my own simple javax.sql.DataSource
implementation, the only method of it I need to work is getConnection: Connection
, but the interface inherits many other methods (which I don't need) from javax.sql.CommonDataSource
and java.sql.Wrapper
. So, I would like to "implement" those unneeded methods a way they wouldn't actually work but would behave an adequate way when called. For example I implement boolean isWrapperFor(Class<?> iface)
as
def isWrapperFor(iface: Class[_]): Boolean = false
and I'd like to implement <T> T unwrap(Class<T> iface)
as
def unwrap[T](iface: Class[T]): T = null
But the last doesn't work: the compiler reports type mismatch.
Will it be correct to use null.asInstanceOf[T]
or is there a better way? Of course I consider just throwing UnsupportedOperationException
instead in this particular case, but IMHO the question can still be interesting.
So, to return a null or default value from a generic method we can make use default(). default(T) will return the default object of the type which is provided.
To use a generic class, put the type in the square brackets in place of A . Class Apple and Banana both extend Fruit so we can push instances apple and banana onto the stack of Fruit . Note: subtyping of generic types is *invariant*.
One of the best ways to understand use cases for generic classes is to look at examples in the Scala standard library. Most Scala generic classes are collections, such as the immutable List, Queue, Set, Map, or their mutable equivalents, and Stack. Collections are containers of zero or more objects.
The reference types such as Objects, and Strings can be nulland the value types such as Int, Double, Long, etc, cannot be null, the null in Scala is analogous to the null in Java.
This is because T
could be a non-nullable type. It works when you enforce T
to be a nullable type:
def unwrap[T >: Null](iface: Class[T]): T = null
unwrap(classOf[String]) // compiles
unwrap(classOf[Int]) // does not compile, because Int is not nullable
The "correct" solution is to do something which will immediately fail. Like so:
def unwrap[T](iface: Class[T]): T = sys.error("unimplemented")
In scala 2.10, this would have been implemented as:
def unwrap[T](iface: Class[T]): T = ???
Because there is a new method in Predef
called ???
. This works because an expression of the form throw new Exception
has the type Nothing
, which is a subtype of any type (it is called bottom in type-theoretical circles).
The reason that this is correct is that it is much better to fail instantly with an error, rather than use a null
which may fail later and obfuscate the cause.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With