اكتب السلامة: ممثلون لم يتم التحقق منه من الكائن
-
25-09-2019 - |
سؤال
أحاول إلقاء كائن إلى فصل العمل الخاص بي ، لكنه يؤدي إلى تحذير:
Type safety: Unchecked cast from Object to Action<ClientInterface>
Action<ClientInterface> action = null;
try {
Object o = c.newInstance();
if (o instanceof Action<?>) {
action = (Action<ClientInterface>) o;
} else {
// TODO 2 Auto-generated catch block
throw new InstantiationException();
}
[...]
شكرا لك على أي مساعدة
المحلول
نعم - هذه نتيجة طبيعية اكتب المحو. لو o
هو في الواقع مثال Action<String>
لن يتم القبض على ذلك من قبل الممثلين - سترى فقط المشكلة عند محاولة استخدامها ، مرور أ ClientInterface
بدلا من سلسلة.
يمكنك التخلص من التحذير باستخدام:
@SuppressWarnings("unchecked")
كتعليق توضيحي للوظيفة ، ولكن لا يمكنك بسهولة فرز المشكلة الأساسية :(
نصائح أخرى
كالعادة ، جون سكيت على حق.
لتوضيح الجزء غير السهل من إجابته:
منح
class ClientAction implements Action<ClientInterface> {}
يمكنك كتابة:
Class<? extends Action<ClientInterface>> c = ClientAction.class;
Action<ClientInterface> action = c.newInstance();
هذا يلغي كل من الممثلين والتحذير ، بسعر إدخال نوع غير عام حتى تتمكن من الاستخدام .class
للحصول على الكتابة بدقة بما فيه الكفاية Class
هدف.
يعني التحذير أن المترجم لا يمكنه ضمان السلامة من النوع حتى لو كان الصب يعمل بشكل جيد في وقت التشغيل. بسبب المحو ، في وقت التشغيل ، يكون الصب مجرد صب للعمل. من الممكن أن تكون الفئة العامة الأساسية من نوع ClientInterface كما هو متوقع. في هذه الحالة ، ستظهر المشكلة لاحقًا (ربما بعد ذلك بكثير) ، باعتبارها classcastexception.
في هذه الحالة المحددة ، أوصي بقمع هذا التحذير المحدد من خلال توجيه المترجم التالي:
@SuppressWarnings("unchecked")
لا تقلق. ذلك لأن برنامج التحويل البرمجي Java ليس لديه طريقة لمعرفة ، ما هو النوع الحقيقي للكائن.
لقد فقدت معلومات النوع بسبب المحو (أي ، تم محو الأنواع المعلمة) ، وبالتالي التحذير. لا يمكنك فعل أي شيء حيال ذلك ، بخلاف تنظيف الكود المحيط بحيث يتم استخدام الأدوية الجنيسة بشكل متكرر ، حتى تتمكن من تمرير معلومات النوع العام وتجنب الإلقاء على الإطلاق.
هذا هو منبوذ. إنه الممثل الديناميكي حيث لا يوجد لدى المترجم أي فكرة عن الكائن الفعلي الذي يشير إليه المرجع.
تحصل على هذا التحذير لأن النوع المستهدف من فريق العمل Action<ClientInterface>
هو نوع المعلمة ولا يمكن للمترجم أن يضمن أن الكائن الذي يتم تصويره هو من نفس النوع.
إذا كنت لا ترغب في قمع هذا التحذير ولا تهتم بمعلمة النوع ، فيمكنك تغيير الرمز إلى هذا باستخدام البطاقات البرية:
Action<?> action = null;
try {
Object o = c.newInstance();
if (o instanceof Action<?>) {
action = (Action<?>) o;
} else {
// TODO 2 Auto-generated catch block
throw new InstantiationException();
}
[...]
هذا أكثر أمانًا لأن ال instanceof
لا يمكن التحقق من ذلك o
هو كائن Action<ClientInterface>
, ، فقط تحقق إذا o
هو كائن Action
منذ أن تكون معلومات النوع العام الإضافي ستكون تمحى في وقت التشغيل.