-7

So I know it's possible somehow to redefine a fundamental int in Java, like to make 1 = 2 so that if you do int x = 1+2, then x will equal 4.

Does anyone know the syntax to do this?

Elec0
  • 2,232
  • 3
  • 19
  • 25
  • 4
    in that case 1+1 will equal 4. – f1sh Aug 30 '18 at 13:40
  • 4
    Could you please show us some code where you want/try to achieve this? Why do you want to be 1 = 2? Don't you like mathematical laws? – deHaar Aug 30 '18 at 13:40
  • Java not support it. – chaos Aug 30 '18 at 13:41
  • Not possible in Java, see this question: https://stackoverflow.com/questions/1686699/operator-overloading-in-java – Eric Aug 30 '18 at 13:44
  • @Eric that's not what I'm talking about. I don't want to overload an operator. I know that is it possible in Java because I have seen it done. – Elec0 Aug 30 '18 at 13:44
  • 3
    It is not possible in Java. The person who showed it to you was fooling you. (Or you are trolling us ...) – Stephen C Aug 30 '18 at 13:45
  • 2
    Maybe it was a hacked compiler or runtime? But AFAIK there is nothing in the language specification that allows this. – Neilos Aug 30 '18 at 13:51
  • 1
    I suppose you could use reflection to alter the value associated with a boxed `Integer` instance. But that wouldn't work with the code you show, because it doesn't use boxing. – Boann Aug 30 '18 at 14:06
  • @Elec0, If you have a source or proof to your claim, please you could share it so that we could all learn something new. Otherwise, I don't think this could be achieved in JAVA. – Ifesinachi Bryan Aug 30 '18 at 14:16
  • @EzeIfesinachiBryan you can check my answer. In particular cases you can break math :-) – pabrantes Aug 30 '18 at 14:17
  • @StephenC most probably he had just heard about Integer cache corruption. It's a particular case but it can be done, like I've shown in my answer – pabrantes Aug 30 '18 at 14:19
  • 1
    Well yes. But that is `Integer` and not `int`. He asked about `int`. – Stephen C Aug 30 '18 at 14:32

1 Answers1

5

Well just for fun, I decided to take a shot at it.

Most probably what you've heard was that you could corrupt the Integer's cache in order to do this.

Before getting any further, here's the code:

package test;

import java.lang.reflect.Field;

public class BreakMath {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
            IllegalArgumentException, IllegalAccessException {

        Class<?> integerCache = Class.forName("java.lang.Integer$IntegerCache");
        Field field = integerCache.getDeclaredField("cache");
        field.setAccessible(true);
        Integer[] cache = (Integer[]) field.get(null);
        cache[1 + 128] = 2;
        System.out.println(1 + 1);
        System.out.println(1 + Integer.valueOf(1));
        System.out.println(Integer.valueOf(1) + Integer.valueOf(1));
    }
}

This outputs the following:

2
3
4

What is really happening?

You are not changing the 1 value in Java. What you are in fact is taking advantage of the internal cache that Integer.class has (in Oracle's JVM and openJDK, might differ in other vendor's JVMs)

Via reflection we get to the Integer cache and we change the value. Since then Integer.valueOf() uses that cache you can achieve this... but if you notice when you are doing the math with plain primitives it does not work. It wouldn't work as well if you had done new Integer(1) (since does not use the cache).

But anywhere you would have the JVM autoboxing you would get into this. So for example if you have the method

public static void printInteger(Integer i) {
        System.out.println(i);
 }

And call it with

printInteger(1)

Autoboxing will happen, the cache will be used and you'll get 2 printed.

Note By default this works from -128 to 128. Which is the default cache, but as you can see in the code you can change the cache size using -XX:AutoBoxCacheMax.

pabrantes
  • 2,161
  • 1
  • 28
  • 34
  • I really appreciate you giving an answer. That might have been what I saw before, but even if it isn't it does what I was hoping for. Also great explanation of what is going on, I didn't know anything about corrupting the cache like that. – Elec0 Aug 30 '18 at 14:10
  • 1
    @Elec0 I've also update with another example (calling a method that will force JVM to box a primtive type into an object). This actually will only work by default from -128 to 128 which is the cache size.. Also keep in mind that this can unleach a full hell of unconsistent behaviour :-) – pabrantes Aug 30 '18 at 14:13