javascalareflectionscala-java-interop

Using reflection to override 2 + 2 = 5


Bear with me, I understand this is a weird problem to have.

I have just stumbled across Java's reflection library, specifically this bit of code from a video by Lex Fridman which overrides 2 + 2 = 5:

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws Exception {
        Class cache = Integer.class.getDeclaredClasses()[0];
        Field c = cache.getDeclaredField("cache");
        c.setAccessible(true);
        Integer[] array = (Integer[]) c.get(cache);
        array[132] = array[133];

        System.out.printf("%d",2 + 2);
    }
}

I am trying to wrap my head around what it's doing by translating it into its equivalent Scala form, but it isn't compiling as Int.getClass.getDeclaredClasses returns an empty array:

import java.lang.reflect.Field

val cache: Class[_] = Int.getClass.getDeclaredClasses.head
// above line throws java.util.NoSuchElementException: next on empty iterator

val c: Field = cache.getDeclaredField("cache")
c.setAccessible(true)
val array = c.get(cache).asInstanceOf[Array[Int]]
array(132) = 5

println(2+2)

Neitherclass nor getClass were methods under Integer when I tried using that, so I tried with Int instead; I was under the impression that Scala's Int is just a wrapper around Java's Integer - is this not the case?

I have also tried:

Why does this work in Java where it doesn't compile with Scala? How can I achieve my stupid goal of 2 + 2 = 5 in Scala?


Solution

  • java.lang.Integer should be instead of scala.Int.

    Int.getClass is getClass invoked on the companion object of class Int, which is wrong.

    Translation of the code into Scala is

    val cache = classOf[Integer].getDeclaredClasses.apply(0)
    val c = cache.getDeclaredField("cache")
    c.setAccessible(true)
    val array = c.get(cache).asInstanceOf[Array[Integer]]
    array(132) = array(133)
    println(2 + 2) // 5
    

    I was under the impression that Scala's Int is just a wrapper around Java's Integer - is this not the case?

    It's not. Normally scala.Int corresponds to Java int.

    https://github.com/scala/scala/blob/2.13.x/src/library/scala/Int.scala