لماذا لا يدعو أسلوب ثابت عن طريق مثيل خطأ المحول البرمجي Java?

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

  •  03-07-2019
  •  | 
  •  

سؤال

أنا متأكد من أنك تعرف كل سلوك أعني رمز مثل:

Thread thread = new Thread();
int activeCount = thread.activeCount();

يثير مترجم تحذير.لماذا ليس خطأ ؟

تحرير:

أن تكون واضحة:السؤال لا علاقة له مع المواضيع.أدرك الخيط الأمثلة غالبا ما تعطى عند مناقشة هذا بسبب احتمال حقا فوضى الأشياء معهم.ولكن في الحقيقة المشكلة هي أن مثل هذا الاستخدام دائما هراء لا يمكنك (بكفاءة) كتابة مثل هذه الدعوة و يعني ذلك.أي مثال على هذا النوع من استدعاء الأسلوب سيكون معتوه.هنا آخر:

String hello = "hello";
String number123AsString = hello.valueOf(123);

مما يجعل الأمر يبدو كما لو أن كل سلسلة سبيل المثال يأتي مع "سلسلة valueOf(int i)" الأسلوب.

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

المحلول

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

فقط للرد على DJClayworth نقطة ، وهنا ما هو مسموح به في C#:

public class Foo
{
    public static void Bar()
    {
    }
}

public class Abc
{
    public void Test()
    {
        // Static methods in the same class and base classes
        // (and outer classes) are available, with no
        // qualification
        Def();

        // Static methods in other classes are available via
        // the class name
        Foo.Bar();

        Abc abc = new Abc();

        // This would *not* be legal. It being legal has no benefit,
        // and just allows misleading code
        // abc.Def();
    }

    public static void Def()
    {
    }
}

لماذا أعتقد أنه مضلل ؟ لأنه إذا أنظر إلى رمز someVariable.SomeMethod() أتوقع أن استخدام قيمة someVariable.إذا SomeMethod() هو أسلوب ثابت ، هذا التوقع غير صحيح ؛ رمز هو خداع لي.و كيف يمكن أن يكون جيد الشيء ؟

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

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

class Base
{
    static void foo()
    {
        System.out.println("Base.foo()");
    }
}

class Derived extends Base
{
    static void foo()
    {
        System.out.println("Derived.foo()");
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Base b = new Derived();
        b.foo(); // Prints "Base.foo()"
        b = null;
        b.foo(); // Still prints "Base.foo()"
    }
}

كما يمكنك أن ترى تنفيذ-القيمة الزمنية b هو تجاهلها تماما.

نصائح أخرى

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

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

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

أنها لا يمكن أن تجعل من الخطأ بعد الآن لأن كل رمز هو بالفعل هناك.

أنا معك في أنه يجب أن يكون خطأ.ربما ينبغي أن يكون هناك خيار/نبذة عن المترجم إلى ترقية بعض التحذيرات من الأخطاء.

تحديث: عندما قدم تأكيد الكلمة في 1.4 ، التي لديها إمكانية مماثلة مشاكل التوافق مع القانون القديم كان متاحة فقط إذا قمت بتعيين مصدر وضع "1.4".أظن أن المرء قد جعل ذلك خطأ في مصدر جديد وضع "جافا 7".ولكن أشك في أنها سوف تفعل ذلك ، معتبرا أن كل المتاعب من شأنه أن يسبب.كما أشار آخرون ، ليس من الضرورة القصوى أن تمنعك من الكتابة مربكة رمز.و تغيير لغة جافا ينبغي أن يقتصر على الضرورة القصوى في هذه المرحلة.

الجواب القصير - اللغة يسمح بذلك ، وهذا ليس خطأ.

على الأرجح نفس المنطقي أن يجعل هذا ليس خطأ:

public class X
{
    public static void foo()
    {
    }

    public void bar()
    {
        foo(); // no need to do X.foo();
    }
}

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

ليس خطأ لأنه جزء من المواصفات ، ولكن من الواضح أنك تسأل عن الحيثيات التي يمكننا تخمين.

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

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

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

الغرض من المثال متغير الإشارة فقط إلى العرض النوع الذي يرفق ثابت.إذا نظرتم الى رمز بايت الاحتجاج ثابت عبر سبيل المثال.staticMethod أو EnclosingClass.staticMethod تنتج نفس الاحتجاج أسلوب ثابت بايت كود.أي إشارة إلى الحالة التي تظهر.

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

ربما يمكنك تغييره في IDE الخاص بك (في الكسوف تفضيلات -> جافا -> مترجم -> الأخطاء تحذيرات)

ليس هناك خيار.في جافا (مثل العديد من الآخرين لانج....) يمكنك الوصول إلى جميع أعضاء ثابتة من فئة خلال اسم الفئة أو مثيل كائن من تلك الفئة.التي من شأنها أن تصل إلى حالة و البرمجيات حل أي واحد يجب عليك استخدام هذا يمنحك المزيد من القراءة.

أنا فقط النظر في هذا:

instanceVar.staticMethod();

أن يكون مختصر لذلك:

instanceVar.getClass().staticMethod();

إذا كان لديك دائما أن تفعل هذا:

SomeClass.staticMethod();

فإنك لن تكون قادرة على الاستفادة من الميراث أساليب ثابتة.

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

تحرير:هذا الجواب خاطئ.انظر التعليقات للحصول على التفاصيل.

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