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

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

سؤال

رمز في النهاية ينتج خطأ في التحويل البرمجي:

NotApplicable.java:7: run() in  cannot be applied to (int)
                run(42);
                ^
1 error

السؤال هو لماذا ؟ لماذا javac أعتقد أنني أدعو تشغيل(), ولا تجد run(int بار)?هذا صحيح يسمى فو(int شريط).لماذا يجب استخدام NotApplicable.هذا.تشغيل(42);?هو هذا الخلل ؟

public class NotApplicable {

    public NotApplicable() {
        new Runnable() {
            public void run() {
                foo(42);
                run(42);
                // uncomment below to fix
                //NotApplicable.this.run(42);
            }
        };
    }

    private void run(int bar) {
    }

    public void foo(int bar) {
    }
}
هل كانت مفيدة؟

المحلول

والتفسير لسلوك نموذج التعليمات البرمجية الخاصة بك هو يعرف أن this أن تكون الفئة التي هي حاليا "معظم" داخل. في هذه الحالة، أنت "معظم" داخل الطبقة الداخلية مجهولة المصدر فرعية runnable وليس هناك طريقة والذي يطابق run(int). لتوسيع نطاق البحث لتحديد أي this كنت تريد استخدام بالقول NotApplicable.this.run(42).

ووJVM سوف تقيم على النحو التالي:

وthis -> تنفذ حاليا مثيل Runnable مع طريقة run()

وNotApplicable.this -> تنفذ حاليا مثيل NotApplicable مع طريقة run(int)

والمترجم سيبحث في شجرة التعشيش للأسلوب الأول الذي يطابق اسم الأسلوب. -بفضل DJClayworth لهذا التوضيح

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

public class Outer{

    public Outer() {
        new Runnable() {
            public void printit() {
                System.out.println( "Anonymous Inner" );
            }
            public void run() {
                printit(); // prints "Anonymous Inner"
                this.printit(); //prints "Anonymous Inner"

                // would not be possible to execute next line without this behavior
                Outer.this.printit(); //prints "Outer" 
            }
        };
    }

    public void printit() {
        System.out.println( "Outer" );
    }
}

نصائح أخرى

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

إذا أعلن Runnable ك فئة فرعية، ثم على المدى الأسلوب () أن إخفاء طريقة تشغيل (الباحث) في الأصل. أي دعوة للتشغيل (...) ستحاول تنفيذ واحد على Runnable، ولكن ستفشل إذا لم يتمكن من مجاراة التوقيعات. منذ لم يتم التصريح فو في الطفل ومن ثم دعا واحد على الوالد.

والمبدأ نفسه يحدث هنا. بحث عن الإشارات إلى "طريقة الاختباء" وأنه ينبغي أن يكون واضحا.

وهذا لأن run يتم إعادة أعلنت عند دخول new Runnable() {} نطاق.جميع الارتباطات السابقة لتشغيل تصبح غير قابلة للوصول.كما لو كنت تفعل هذا:

import java.util.*;

public class tmp
{
  private int x = 20;
  public static class Inner
  {
      private List x = new ArrayList();
      public void func()
      {
          System.out.println(x + 10);
      }
  }

  public static void main(String[] args)
  {
    (new Inner()).func();
  }
}

المترجم لن ابحث عن شيء يطابق نوع x كل وسيلة تصل نطاق المكدس, سوف توقف عندما يجد المراجع الأولى و يرى أن الأنواع غير متوافقة.

ملاحظة: انها ليست كما لو أنه لا هل هذا...انه فقط للحفاظ على سلامتك, لقد تقرر أنه يجب أن لا.

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