جافا ليست مرجعية أبدا، أليس كذلك؟ ... أليس كذلك؟ [مكرر

StackOverflow https://stackoverflow.com/questions/795160

سؤال

ممكن مكررة:
هل جافا "مرجعي"؟

لقد وجدت طريقة جافا غير عادية اليوم:

private void addShortenedName(ArrayList<String> voiceSetList, String vsName)
{
     if (null == vsName)
       vsName = "";
     else
       vsName = vsName.trim();
     String shortenedVoiceSetName = vsName.substring(0, Math.min(8, vsName.length()));
     //SCR10638 - Prevent export of empty rows.
     if (shortenedVoiceSetName.length() > 0)
     {
       if (!voiceSetList.contains("#" + shortenedVoiceSetName))
         voiceSetList.add("#" + shortenedVoiceSetName);
     }
}

وفقا لكل ما قرأته عن سلوك Java لمجرد المتغيرات والأجسام المعقدة أم لا، يجب أن يفعل هذا الرمز شيئا بالضبط. لذلك أم ... هل أنا أفتقد شيئا هنا؟ هل هناك بعض الدقة التي فقدت علي، أو هل ينتمي هذا القانون إلى thedailywtf؟

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

المحلول

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

مثال:

private void goodChangeDog(Dog dog) {
    dog.setColor(Color.BLACK); // works as expected!
}
private void badChangeDog(Dog dog) {
    dog = new StBernard(); // compiles, but has no effect outside the method
}

يحرر: ماذا يعني هذا القضية في هذه الحالة voiceSetList ربما تغيير نتيجة لهذه الطريقة (قد يكون لها عنصر جديد يضاف إليه)، والتغييرات الموجودة عليها vsName لن تكون مرئية خارج الطريقة. لمنع الارتباك، غالبا ما يمثل علامة أسلوبي final, ، مما يجعلهم من إعادة تعيينه (بطريق الخطأ أم لا) داخل الطريقة. هذا من شأنه أن يبقي المثال الثاني من تجميع على الإطلاق.

نصائح أخرى

يمر جافا المراجع حسب القيمة, ، حتى تحصل على نسخة من المرجع، ولكن الكائن المشار إليه هو نفسه. وبالتالي فإن هذه الطريقة تعدل قائمة الإدخال.

يتم تمرير المراجع نفسها حسب القيمة.

من Java كيفية البرنامج، الطبعة الرابعة من Deitel & Deitel: (PG. 329)

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

استخدم هذا الكتاب عند تعلم جافا في الكلية. مرجع رائع.

إليك مقال جيد يشرحه.http://www.javaworld.com/javaworld/javaqa/2000-05-03-QA-0526-Pass.html.

حسنا، يمكن أن يتلاعب ArrayList - أي كائن ... إذا كنت تمر مرجع كائن حول (حتى مرت بالقيمة)، فسوف ينعكس التغييرات الموجودة على هذا الكائن في المتصل. هل هذا هو السؤال؟

أعتقد أنك مرتبك لأنه تم تعديل VSNAME. ولكن في هذا السياق، فهو مجرد متغير محلي، في نفس المستوى بالضبط كما shortenedvoicesetname.

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

لمزيد من التفاصيل، انظر إجابتي هنا: في جاوة، ما هي نسخة ضحلة؟ (انظر أيضا إجاباتي الأخرى)

بالمناسبة، هناك بعض المزايا لأن الصفائف هي فقط المؤشرات: يمكنك استخدامها (AB) ككائنات متزامنة!

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