This page is no longer maintained — Please continue to the home page at www.scala-lang.org

getClass returns Class[_]?

12 replies
ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.

Hi,

Probably this is a complicated issue, but shouldn't the following work?

val xClass: Class[X] = new X().getClass //it returns Class[_], nor Class[X]

val integerClass: Class[Integer] = new Integer(5).getClass //similar error

Thanks,
Dimitris

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: getClass returns Class[_]?
Andreou,
The return type (in the Java apis) of getClass is Class<?>:  Class<?>getClass() 
          Returns the runtime class of this Object.
Scala is faithfully returning what the Java APIs define.
Sorry.
David
On Sun, Jan 18, 2009 at 4:04 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
Hi,

Probably this is a complicated issue, but shouldn't the following work?

val xClass: Class[X] = new X().getClass //it returns Class[_], nor Class[X]

val integerClass: Class[Integer] = new Integer(5).getClass //similar error

Thanks,
Dimitris



--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Ismael Juma
Joined: 2009-01-07,
User offline. Last seen 42 years 45 weeks ago.
Re: getClass returns Class[_]?
On Sun, 2009-01-18 at 16:12 -0800, David Pollak wrote: > Andreou, > > > The return type (in the Java apis) of getClass is Class<?>: > Class<?> > getClass() > Returns the runtime class > of this Object. It's more complicated than that. The following compiles: Class<? extends Integer> klass = new Integer(2).getClass(); The javadoc explains:

The actual result type is {@code Class<? extends |X|>} * where {@code |X|} is the erasure of the static type of the * expression on which {@code getClass} is called. For * example, no cast is required in this code fragment:

* *

* {@code Number n = 0; }
* {@code Class<? extends Number> c = n.getClass(); } *

* Ismael
ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: getClass returns Class[_]?
O/H Ismael Juma έγραψε: > On Sun, 2009-01-18 at 16:12 -0800, David Pollak wrote: > >> Andreou, >> >> >> The return type (in the Java apis) of getClass is Class<?>: >> Class<?> >> getClass() >> Returns the runtime class >> of this Object. >> > > It's more complicated than that. The following compiles: > > Class<? extends Integer> klass = new Integer(2).getClass(); > > The javadoc explains: > >

The actual result type is {@code Class<? extends |X|>} > * where {@code |X|} is the erasure of the static type of the > * expression on which {@code getClass} is called. For > * example, no cast is required in this code fragment:

> * > *

> * {@code Number n = 0; }
> * {@code Class<? extends Number> c = n.getClass(); } > *

> * > > Ismael > I guess it would be nice if similar compiler magic was implemented in Scala too. (Although not big deal, since the type of the expression is available, and we can simply add an never-failing asInstanceOf[ ])
James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: getClass returns Class[_]?
This is Scala.  We don't need no stinkin' compiler magic, we got it already :-)

class NiceObject[T <: AnyRef](x : T) {
  def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}

implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)

scala> "Hello world".niceClass                                       
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String



On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou <jim.andreou@gmail.com> wrote:


 
I guess it would be nice if similar compiler magic was implemented in Scala too.
(Although not big deal, since the type of the expression is available, and we can simply add an never-failing asInstanceOf[ <type> ])

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: getClass returns Class[_]?


On Sun, Jan 18, 2009 at 4:52 PM, James Iry <jamesiry@gmail.com> wrote:
This is Scala.  We don't need no stinkin' compiler magic, we got it already :-)

class NiceObject[T <: AnyRef](x : T) {
  def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}

implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)

scala> "Hello world".niceClass                                       
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String

Very nice. 




On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou <jim.andreou@gmail.com> wrote:


 
I guess it would be nice if similar compiler magic was implemented in Scala too.
(Although not big deal, since the type of the expression is available, and we can simply add an never-failing asInstanceOf[ <type> ])




--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: getClass returns Class[_]?

lol! You're right. (You could even do it a bit more nice with Class[T]
instead of Class[_ <: T] )

Let me make an observation here:
All problems in Java can be solved with an annotation. In Scala, with an
implicit conversion.

O/H James Iry έγραψε:
> This is Scala. We don't need no stinkin' compiler magic, we got it
> already :-)
>
> class NiceObject[T <: AnyRef](x : T) {
> def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
> }
>
> implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
>
> scala> "Hello world".niceClass
> res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
>
>
>
> On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou
> > wrote:
>
>
>
>
>
> I guess it would be nice if similar compiler magic was implemented
> in Scala too.
> (Although not big deal, since the type of the expression is
> available, and we can simply add an never-failing asInstanceOf[
> ])
>
>

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: getClass returns Class[_]?
Except that Class[T] isn't right because Class isn't marked as covariant by Java - Java doesn't have that concept.   If Sub is a subtype of Base then

val someSub : Sub = ...
val x : Base = someSub // a legal cast

val klass = x.niceClass 

what type should klass have?  Dynamically speaking it's in fact a Class[Sub], but the static type system can't know that. By your scheme it would be Class[Base], but Class[Base] isn't a supertype of Class[Sub] so we've gone sideways a bit.  By my scheme it gets the best type the static type system can apply: Class[_ <: Base] - it's a Class for some type that is a subtype of Base, but the static type system doesn't know which.

On Sun, Jan 18, 2009 at 5:04 PM, Dimitris Andreou <jim.andreou@gmail.com> wrote:
lol! You're right. (You could even do it a bit more nice with Class[T] instead of Class[_ <: T] )

Let me make an observation here:
All problems in Java can be solved with an annotation. In Scala, with an implicit conversion.


O/H James Iry έγραψε:
This is Scala.  We don't need no stinkin' compiler magic, we got it already :-)

class NiceObject[T <: AnyRef](x : T) {
 def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}

implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)

scala> "Hello world".niceClass                                       res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String



On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou <jim.andreou@gmail.com <mailto:jim.andreou@gmail.com>> wrote:



       
   I guess it would be nice if similar compiler magic was implemented
   in Scala too.
   (Although not big deal, since the type of the expression is
   available, and we can simply add an never-failing asInstanceOf[
   <type> ])




ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: getClass returns Class[_]?

O/H James Iry έγραψε:
> Except that Class[T] isn't right because Class isn't marked as
> covariant by Java - Java doesn't have that concept.

> If Sub is a subtype of Base then
>
> val someSub : Sub = ...
> val x : Base = someSub // a legal cast
>
> val klass = x.niceClass
>
> what type should klass have?
Class[Base], sure enough.
> Dynamically speaking it's in fact a Class[Sub], but the static type
> system can't know that. By your scheme it would be Class[Base], but
> Class[Base] isn't a supertype of Class[Sub]
Disclaimer: I'm used to java generics semantics, I'm not sure if these
translate very well in scala, but anyway, hopefully they do:

Class[T] and Class[_ <: T] are practically equivalent since Class
doesn't have any method that accepts T (yes, this means that the java
compiler magic could safely translate T.getClass() expressions to
Class instead of Class<? extends T>). But the former is also more
specific, so it can be applied to more method signatures, specifically,
it can be applied to every method your Class[_ <: T] can be applied, but
it can also be applied to an expected method argument of type Class[T],
whereas Class[_ <: T] cannot. So we have two synonyms that the one can
be type-safely be applied to more methods, so it should be preferred.

> so we've gone sideways a bit. By my scheme it gets the best type the
> static type system can apply: Class[_ <: Base] - it's a Class for some
> type that is a subtype of Base, but the static type system doesn't
> know which.
But Class[Base] already means a "class for some type that is a subtype
of Base". Think of a method that returns "Base". That's exactly what it
means. You get back a subtype.
>
> On Sun, Jan 18, 2009 at 5:04 PM, Dimitris Andreou
> > wrote:
>
> lol! You're right. (You could even do it a bit more nice with
> Class[T] instead of Class[_ <: T] )
>
> Let me make an observation here:
> All problems in Java can be solved with an annotation. In Scala,
> with an implicit conversion.
>
>
> O/H James Iry ������:
>
> This is Scala. We don't need no stinkin' compiler magic, we
> got it already :-)
>
> class NiceObject[T <: AnyRef](x : T) {
> def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
> }
>
> implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
>
> scala> "Hello world".niceClass
> res11: java.lang.Class[_ <: java.lang.String] = class
> java.lang.String
>
>
>
> On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou
>
> >>
> wrote:
>
>
>
>
> I guess it would be nice if similar compiler magic was
> implemented
> in Scala too.
> (Although not big deal, since the type of the expression is
> available, and we can simply add an never-failing asInstanceOf[
> ])
>
>
>
>

James Iry
Joined: 2008-08-19,
User offline. Last seen 1 year 23 weeks ago.
Re: getClass returns Class[_]?

But Class[Base] already means a "class for some type that is a subtype of Base". Think of a method that returns "Base". That's exactly what it means. You get back a subtype.

Nope.  No more than ArrayList[String] is a subtype of ArrayList[Object].   The rest of your arugment is that, unlike ArrayList, Class could be covariant.  You're probably right. Unfortunately, it isn't.
Erkki Lindpere
Joined: 2008-12-19,
User offline. Last seen 42 years 45 weeks ago.
Re: getClass returns Class[_]?

This is unrelated, but I'm curious, is there an advantage to creating a
non-anonymous class for extension methods?

I've lately been doing all such conversions as anonymous classes:

implicit def toNiceObject[T <: AnyRef](x : T) = new {
def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}

It's shorter and doesn't pollute the namespace. The only disadvantage I
can think of is documentation. Although possibly IDEs and ScalaDoc
should be able use method documentation in anonymous classes as well, I
think?

Erkki

James Iry wrote:
> This is Scala. We don't need no stinkin' compiler magic, we got it
> already :-)
>
> class NiceObject[T <: AnyRef](x : T) {
> def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
> }
>
> implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
>
> scala> "Hello world".niceClass
> res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
>
>
>
> On Sun, Jan 18, 2009 at 4:33 PM, Dimitris Andreou
> > wrote:
>
>
>
>
>
> I guess it would be nice if similar compiler magic was implemented
> in Scala too.
> (Although not big deal, since the type of the expression is
> available, and we can simply add an never-failing asInstanceOf[
> ])
>
>

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: getClass returns Class[_]?

On Mon, Jan 19, 2009 at 11:29:44AM +0200, Erkki Lindpere wrote:
> This is unrelated, but I'm curious, is there an advantage to creating a
> non-anonymous class for extension methods?

Unfortunately, yes.

> I've lately been doing all such conversions as anonymous classes:
>
> implicit def toNiceObject[T <: AnyRef](x : T) = new {
> def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
> }

If you look at the bytecode for the anonymous version you'll see a bunch of reflection that the
named version doesn't have to do, so the shorter version is significantly slower. This may
improve in the future as JDK7 promises some helpful features.

ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: getClass returns Class[_]?

O/H James Iry έγραψε:
>
> But Class[Base] already means a "class for some type that is a
> subtype of Base". Think of a method that returns "Base". That's
> exactly what it means. You get back a subtype.
>
>
> Nope. No more than ArrayList[String] is a subtype of
> ArrayList[Object]. The rest of your arugment is that, unlike
> ArrayList, Class could be covariant. You're probably right.
> Unfortunately, it isn't.
James, you're confusing what I say. I never said that Class[Sub] is a
subtype of Class[Base]. It is not. Who cares. Did I say "go ahead and
create a method that takes Class[Base]"? If I did, then I would miss the
possibility of applying Class[Sub]. But I can always make such a
function that takes a Class[X] where X <: Base. That's entirely irrelevant.

To close the matter, just consider that Class[Base] is a subtype of
Class[_ <: Base], (not the other way around). So a Class[Base] also *is*
a Class[_ <: Base]. Now abstract a little to see the big picture. In
object oriented languages, the basic fact is that a value of a subtype
can be assigned to more places (variables, method args, methods to it)
than a value of a supertype. It is more useful - literally it simply has
more uses. So wherever you can, *return the more precise subtype you
can*. On the contrary, a supertype can be *assigned from* more places
than a subtype (such as storing the result of a function, or storing a
method parameter). You can do less things with it, but can represent a
wider domain of values. So wherever you can, *accept the more general
supertype you can*. These are the two faces of the same coin, and they
are pretty basic and hopefully you won't deny them.

So, I suggest switching it to returning Class[Base], and if you don't
like it, just store the method result into a Class[_ <: Base] variable,
nobody will notice a thing :)

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland