W jaki sposób można rozszerzyć język Java, aby wprowadzić przechodzenie przez odniesienie?

Java jest wartością „pass-by-value”. Jak można zmodyfikować język, aby wprowadzić przechodzenie przez odniesienie (lub jakieś równoważne zachowanie)?

Weźmy na przykład coś takiego

public static void main(String[] args) {
    String variable = "'previous String reference'";
    passByReference(ref variable);
    System.out.println(variable); // I want this to print 'new String reference'
}

public static void passByReference(ref String someString) {
    someString = "'new String reference'";
}

który (bezref) kompiluje do następującychkod bajtowy

  public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String 'previous String reference'
       2: astore_1
       3: aload_1
       4: invokestatic  #3                  // Method passByReference:(Ljava/lang/String;)V
       7: return

  public static void passByReference(java.lang.String);
    Code:
       0: ldc           #4                  // String 'new String reference'
       2: astore_0
       3: return

Kod w3: ładuje odwołanie do stosu ze zmiennejvariable.

Jedną z możliwości, które rozważam, jest sprawienie, aby kompilator określił, że metoda jest przekazywana przez odniesienie, ewentualnie zrefi zmień metodę, aby zaakceptować obiekt Holder, który przechowuje to samo odwołanie co nasza zmienna. Gdy metoda zakończy się i ewentualnie zmieni to odniesienie w uchwycie, zmienna wartości strony wywołującej zostanie zastąpiona wartością odniesienia posiadacza.

Powinien być skompilowany do odpowiednika tego

public static void main(String[] args) {
    String variable = "'previous String reference'";
    Holder holder = Holder.referenceOf(variable);
    passByReference2(holder);
    variable = (String) holder.getReference(); // I don't think this cast is necessary in bytecode
    System.out.println(variable);
}

public static void passByReference(Holder someString) {
    someString.setReference("'new String reference'");
}

gdzieHolder może coś w tym stylu

public class Holder {
    Object reference;
    private Holder (Object reference) {
        this.reference = reference;
    }
    public Object getReference() {
        return this.reference;
    }
    public void setReference(Object reference) {
        this.reference = reference;
    }
    public static Holder referenceOf(Object reference) {
        return new Holder(reference);
    }
}

Gdzie to może się nie powieść lub jak możesz to poprawić?

questionAnswers(10)

yourAnswerToTheQuestion