How can you extend Java to introduce passing by reference?

前端 未结 10 2223
天命终不由人
天命终不由人 2020-12-24 06:19

Java is pass-by-value. How could you modify the language to introduce passing by reference (or some equivalent behavior)?

Take for example something like

<         


        
10条回答
  •  天命终不由人
    2020-12-24 07:20

    Think about how it might be implemented with a primitive type, say int. Java - the JVM, not just the language - does not have any "pointer" type to a local variable, on the frame (method stack) or the operand stack. Without that, it is not possible to truly pass by reference.

    Other languages that support pass-by-reference use pointers (I believe, though I don't see any other possibility). C++ references (like int&) are pointers in disguise.

    I've thought of creating a new set of classes that extend Number, containing int, long, etc. but not immutable. This could give some of the effect of passing primitives by reference - but they won't be auto-boxed, and some other features might not work.

    Without support in the JVM, you can't have real pass-by-reference. Sorry, but that's my understanding.

    BTW, there are already several Reference-type classes (like you'd like for Holder). ThreadLocal<> (which has get() and set()), or the Reference extenders, like WeakReference (which I think only have get()).

    Edit: After reading some other answers, I'd suggest that ref be a form of auto-boxing. Thus:

    class ReferenceHolder {
        T referrent;
        static  ReferenceHolder valueOf(T object) {
            return new ReferenceHolder(object);
        }
        ReferenceHolder(T object) { referrent = object; }
        T get()            { return referrent; }
        void set(T value)  { referrent = value; }
    }
    
    class RefTest {
        static void main() {
            String s = "Hello";
            // This is how it is written...
            change(s);
            // but the compiler converts it to...
            ReferenceHolder $tmp = ReferenceHolder.valueOf(s);
            change($tmp);
            s = $tmp.get();
        }
        // This is how it is written...
        static void change(ref Object s) {
            s = "Goodbye";              // won't work
            s = 17;             // *Potential ClassCastException, but not here*
        }
        // but the compiler converts it tothe compiler treats it as:
        static  void change(ReferenceHolder obj) {
            obj.set((T) "Goodbye");     // this works
            obj.set((T) 17);    // *Compiler can't really catch this*
        }
    }
    

    But see where there is potential for putting the wrong kind of type in the ReferenceHolder? If genericized properly, the compiler may be able to warn sometimes, but as you likely want the new code to resemble normal code as much as possible, there is the possibility of a CCEx with each auto-ref call.

提交回复
热议问题