Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

not found: value getClass #12025

Closed
matobet opened this issue Jun 2, 2020 · 10 comments
Closed

not found: value getClass #12025

matobet opened this issue Jun 2, 2020 · 10 comments

Comments

@matobet
Copy link

matobet commented Jun 2, 2020

reproduction steps

using Scala (2.13.2),

class Howdy(c: Class[_]) {
  def this() = this(getClass)
}

problem

Fails to compile with

Error:(8, 21) not found: value getClass
  def this() = this(getClass)

The above class compiles successfully with Scala 2.12.7.

@joroKr21
Copy link
Member

joroKr21 commented Jun 2, 2020

This is intentional: scala/scala#8541
The behaviour was quite surprising because getClass referred to Predef.getClass and not this.getClass.

@matobet
Copy link
Author

matobet commented Jun 2, 2020

@joroKr21 is there a workaround for my case? because attempting def this() = this(this.getClass) results in

Error:(8, 21) this can be used only in a class, object, or template
  def this() = this(this.getClass)

@Jasper-M
Copy link
Member

Jasper-M commented Jun 2, 2020

def this() = this(classOf[Howdy])

@matobet
Copy link
Author

matobet commented Jun 2, 2020

Ok, so you are saying the 2.12.7 code was incorrect all way long. But why is it illegal to do this.getClass? I believe Java allows you to do this.

@matobet
Copy link
Author

matobet commented Jun 2, 2020

@Jasper-M actually howdy is an abstract base class that really wants to do something with the concrete Class[_] of its child... Thats why I need the polymorphic call to getClass here.

@Jasper-M
Copy link
Member

Jasper-M commented Jun 2, 2020

I'm not really sure how your old code accomplished that since constructors are not inherited. Maybe your minimized code is now too small to clearly see what the use case was. Anyway it's probably better to ask the question on e.g. users.scala-lang.org.

@joroKr21
Copy link
Member

joroKr21 commented Jun 2, 2020

I can't think of a workaround that would cover all use cases.
But the original code wasn't working as intended either.
Java has the same limitation: https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8.7.1

An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs.

@Jasper-M
Copy link
Member

Jasper-M commented Jun 2, 2020

You could consider

class Howdy(c: Option[Class[_]] = None) {
  val clazz = c.getOrElse(this.getClass)
}

@dwijnand
Copy link
Member

dwijnand commented Jun 2, 2020

I believe Java allows you to do this.

It doesn't:

$ cat C.java && javac C.java
class C {
  private final Class<?> cls;

  C(Class<?> cls) {
    this.cls = cls;
  }

  C() {
    this(getClass());
  }
}
C.java:9: error: cannot reference this before supertype constructor has been called
    this(getClass());
         ^
1 error

@matobet
Copy link
Author

matobet commented Jun 2, 2020

Indeed, the legacy code I'm now migrating to Scala 2.13 must have accidentally depended on the old 2.12 behavior where it invoked Predef.getClass and was thus incorrect. It turns out those ctor overloads were never used and subclasses always supplied their specific classOf[Child].

Thanks everyone for the quick reactions and answers! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants