سؤال

هذا السؤال لديه بالفعل إجابة هنا:

كنت محيرًا نوعًا ما عندما رأيت الرمز التالي لم يعمل كما هو متوقع.

اعتقدت أن جافا مرت دائمًا المتغيرات بالمراجع إلى وظائف. لذلك ، لماذا لا تستطيع الوظيفة إعادة تعيين المتغير؟

public static void main(String[] args) {

  String nullTest = null;

  setNotNull(nullTest);

  System.out.println(nullTest);
}

private static void setNotNull(String s) {
  s = "not null!";
}

مخرجات هذا البرنامج null.

هل كانت مفيدة؟

المحلول

يتم تمرير الإشارات إلى الكائنات بواسطة القيمة في Java ، لا يؤدي التعيين إلى المتغير المحلي داخل الطريقة إلى تغيير المتغير الأصلي. المتغير المحلي فقط s يشير إلى سلسلة جديدة. قد يكون من الأسهل فهمها بفن ASCII الصغير.

في البداية لديك هذا:

------------
| nullTest |
------------
     |
    null

عندما تقوم أولاً بإدخال الطريقة setNotnull ستحصل على ملف نسخة من القيمة من nulltest في s. في هذه الحالة ، تكون قيمة nulltest مرجعًا فارغًا:

------------    ------------
| nullTest |    |    s     |
------------    ------------
     |               |
    null            null

ثم إعادة تعيين S:

------------    ------------
| nullTest |    |    s     |
------------    ------------
     |               |
    null         "not null!"

ثم اترك الطريقة:

------------
| nullTest |
------------
     |
    null

نصائح أخرى

لا تمر Java بالرجوع إليها ، فهي تمرر قيمة المرجع. عندما تقوم بتعيين s="not null", ، أنت تقوم بإعادة تعيين هذه القيمة.

كنت آمل أن أفعل شيئًا مثل setNotnull (myobject O) دون استخدام O = setNotnull (O)

ببساطة ، لا يمكنك ذلك. الأقرب الذي ستحصل عليه هو شيء من هذا القبيل:

public class MyRef<T> {
    private T obj;

    public T get() {
        return obj;
    }

    public void set(T obj) {
        this.obj = obj;
    }

    public void setNotNull(T obj) {
        if (this.obj == null) {
            this.obj = obj;
        }
    }
}

MyRef<MyObj> ref = new MyRef<MyObj>();
ref.setNotNull(xyz);
System.err.println(ref.get());

وهو كل شيء عقلاني إلى حد ما ، وربما لا يستحق كل هذا الجهد.

s =

هذا هو السبب. أنت تقوم بتعيين S ، وليس تعديل الكائن الذي يشير إليه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top