Skip to content

Final methods in traits are not compiled as final #11485

@ultrasecreth

Description

@ultrasecreth

In 2.13.0-RC1, if we write this simple code

import java.lang.reflect.Modifier.isFinal

trait HaveFinalMethod {
  def normalMethod: String = "normal"
  final def finalMethod: String = "final"
}

class Child extends HaveFinalMethod

object Main {
  def main(args: Array[String]): Unit = {
    println(isFinal(classOf[HaveFinalMethod].getMethod("normalMethod").getModifiers)) //false
    println(isFinal(classOf[HaveFinalMethod].getMethod("finalMethod").getModifiers)) //false but should be true!

    println(isFinal(classOf[Child].getMethod("normalMethod").getModifiers)) //false
    println(isFinal(classOf[Child].getMethod("finalMethod").getModifiers))  //true (as it should be)
  }
}

Then we'll see how finalMethod in HaveFinalMethod is not actually marked as final, which, on top of being inconsistent with what happens when we test the same on Child, causes issues with frameworks that use reflection.

if we make Child a trait instead of a class, then the problem is also present when inspecting finalMethod.

trait HaveFinalMethod {
  def normalMethod: String = "normal"
  final def finalMethod: String = "final"
}

trait Child extends HaveFinalMethod

object Main {
  def main(args: Array[String]): Unit = {
    println(isFinal(classOf[HaveFinalMethod].getMethod("normalMethod").getModifiers)) //false
    println(isFinal(classOf[HaveFinalMethod].getMethod("finalMethod").getModifiers)) //false but should be true!

    println(isFinal(classOf[Child].getMethod("normalMethod").getModifiers)) //false
    println(isFinal(classOf[Child].getMethod("finalMethod").getModifiers))  //false but should be true!
  }
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions