سؤال

ريان Delucchi وطلب <لأ href = "https://stackoverflow.com/questions/194698/how -to الحمل واحد في جرة ملف-في-وقت التشغيل # 194712 "> هنا في تعليق رقم 3 ل<لأ href =" https://stackoverflow.com/users/4725/tom-hawtin-tackline "> الجواب توم Hawtin الصورة:

<اقتباس فقرة>   

وماذا Class.newInstance () "الشر"؟

وهذا ردا على نموذج التعليمات البرمجية:

// Avoid Class.newInstance, for it is evil.
Constructor<? extends Runnable> ctor = runClass.getConstructor();
Runnable doRun = ctor.newInstance();

وهكذا، لماذا هو الشر؟

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

المحلول

وتوضح وثائق API جافا لماذا (<لأ href = "http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance ()" يختلط = "noreferrer" > http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance () ):

<اقتباس فقرة>   

لاحظ أن هذه الطريقة تنتشر أي استثناء القيت من قبل منشئ nullary، بما في ذلك استثناء محددا. استخدام هذه الطريقة تجاهلت بشكل فعال استثناء فحص وقت الترجمة التي لولاها أن يقوم بها المترجم. طريقة Constructor.newInstance يتجنب هذه المشكلة عن طريق التفاف أي استثناء القيت من قبل منشئ في (محددة) InvocationTargetException.

وبعبارة أخرى، فإنه يمكن هزيمة نظام التحقق من الاستثناءات.

نصائح أخرى

واحد من الأسباب:

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

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

وأنا لا أعرف لماذا لم يقدم أي واحد مثال بسيط على أساس تفسير لهذا، بالمقارنة مع Constructor::newInstance على سبيل المثال، منذ <م> أخيرا تم إهمال Class::newInstance منذ جافا-9.

وافترض أن لديك هذه فئة بسيطة جدا (لا يهم أن ما تم كسرها):

static class Foo {
    public Foo() throws IOException {
        throw new IOException();
    }
}

ومحاولة إنشاء مثيل من ذلك عن طريق التفكير. Class::newInstance أولا:

    Class<Foo> clazz = ...

    try {
        clazz.newInstance();
    } catch (InstantiationException e) {
        // handle 1
    } catch (IllegalAccessException e) {
        // handle 2
    }

ووصف هذا سيؤدي إلى IOException التي القيت - المشكلة هي أن التعليمات البرمجية لا التعامل معها، لا handle 1 ولن handle 2 قبض عليه

في المقابل عندما يفعلون ذلك عن طريق Constructor:

    Constructor<Foo> constructor = null;
    try {
        constructor = clazz.getConstructor();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }

    try {
        Foo foo = constructor.newInstance();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        System.out.println("handle 3 called");
        e.printStackTrace();
    }

والتي تتعامل مع وسوف يطلق 3، وبالتالي سوف التعامل معها.

وعلى نحو فعال، Class::newInstance يتجاوز معالجة الاستثناء - الذي كنت حقا لا تريد

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