Java

Javaでもa == 1 && a == 2 && a == 3でtrueって出力させたい(Javassist二番煎じ編)

前置き

『Javaでもa == 1 && a == 2 && a == 3でtrueって出力させたい』のJavassistを使って変数aの値を書き換えるバージョンです。

ソース

EqualsA.java
package com.example;

public class EqualsA {

    private int a;

    public void execute() {
        System.out.println("start");

        if (a == 1 && a == 2 && a == 3) {
            System.out.println(true);
        } else {
            System.out.println(false);
        }

        System.out.println("end");
    }
}
EqualsMain.java
package com.example;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.expr.ExprEditor;
import javassist.expr.FieldAccess;

public class EqualsMain {

    public static void main(String[] args) throws Exception {
        convert();

        new EqualsA().execute();
    }

    static void convert() throws Exception {
        ClassPool classPool = ClassPool.getDefault();
        CtClass cc = classPool.get("com.example.EqualsA");
        cc.instrument(new ExprEditor() {

            private int i = 1;

            @Override
            public void edit(FieldAccess f) throws CannotCompileException {
                if (f.getFieldName().equals("a")) {
                    f.replace(String.format("$_ = %d;", i++));
                }
            }
        });

        cc.toClass();
    }
}

ExprEditorではローカル変数は扱えないようですがフィールドは扱えました。

おまけ(Scala)

object EqualsA {
  def main(args: Array[String]): Unit = {
    val a = Int(1)
    if (a == 1 && a == 2 && a == 3) {
      println("true")
    } else {
      println("false")
    }
  }

  case class Int(n: scala.Int) {
    override def equals(other: Any) = true
  }
}