لماذا لا يمكنني استدعاء أسلوب خارج مجهول فئة من نفس الاسم
-
05-07-2019 - |
سؤال
رمز في النهاية ينتج خطأ في التحويل البرمجي:
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
كل وسيلة تصل نطاق المكدس, سوف توقف عندما يجد المراجع الأولى و يرى أن الأنواع غير متوافقة.
ملاحظة: انها ليست كما لو أنه لا هل هذا...انه فقط للحفاظ على سلامتك, لقد تقرر أنه يجب أن لا.