Предупреждения в Java при прехвърляне към общ тип

Translate

Имам някакъв родов код, от който не мога да разбера как законно да предотвратя получаването на предупреждения от; За момента използвам @SuppressWarnings ("неотметнато"), тъй като изглежда, че прехвърлянето на общ тип не може да се направи без предупреждения.

Как мога да се отърва от анотацията?

Това, което имам е:

public MyObject(SharedContext<Object> ctx) {
    super(ctx); // set protected field 'context'
    ...
    context.set("Input Fields"  ,Collections.synchronizedMap(new TreeMap<String,Pair<String,Boolean>>(String.CASE_INSENSITIVE_ORDER)));
    context.set("Output Fields" ,Collections.synchronizedMap(new TreeMap<String,String>              (String.CASE_INSENSITIVE_ORDER)));
    context.set("Event Registry",new EventRegistry(log)                                                                              );
    }

@SuppressWarnings("unchecked")
protected void startup() {
    inputFields     =(Map<String,Pair<String,Boolean>>)context.get("Input Fields"  ,null);
    outputFields    =(Map<String,String>              )context.get("Output Fields" ,null);
    eventRegistry   =(EventRegistry                   )context.get("Event Registry",null);
    ...
    }

Контекстът на защитената променлива е типSharedContext<Object>.

Без анотацията компилаторът дава предупреждения:

...\MyClass.java:94: warning: [unchecked] unchecked cast
found   : java.lang.Object
required: java.util.Map<java.lang.String,com.mycompany.Pair<java.lang.String,java.lang.Boolean>>
    inputFields     =(Map<String,Pair<String,Boolean>>)context.get("Input Fields"  ,null);
                                                                  ^
...\MyClass.java:95: warning: [unchecked] unchecked cast
found   : java.lang.Object
required: java.util.Map<java.lang.String,java.lang.String>
    outputFields    =(Map<String,String>              )context.get("Output Fields" ,null);
This question and all comments follow the "Attribution Required."

Всички отговори

Translate

След някои по-нататъшни проучвания вярвам, че намерих разумна алтернатива, която поне ограничава анотацията за потискане само до един глобален статичен полезен метод за извършване на непроверен глас.

Програмата за самостоятелно тестване, която следва, трябва да бъде достатъчно ясна:

public class Generics
{

static public void main(String[] args) {
    Generics.test();
    }

static private void test() {
    Map<String,Object> ctx=new TreeMap<String,Object>();
    Map<String,Object> map=new TreeMap<String,Object>();
    Map<String,Object> tst;

    ctx.put("Test",map);
    tst=uncheckedCast(ctx.get("Test"));
    }

@SuppressWarnings({"unchecked"})
static public <T> T uncheckedCast(Object obj) {
    return (T)obj;
    }

}

Друг блог предлага подобрение на този полезен метод:

@SuppressWarnings("unchecked") 
public static <T, X extends T> X uncheckedCast(T o) {
    return (X) o;
    }

принуждавайки върнатото да бъде подклас на параметъра, предаден.

Ако приемем, че съм поставил un CheckCast в публичния клас GenUtil, методът ми за стартиране във въпроса няма да издава (безполезни) предупреждения и да изглежда така:

protected void startup() {
    inputFields  =GenUtil.uncheckedCast(context.get("Input Fields"  ,null));
    outputFields =GenUtil.uncheckedCast(context.get("Output Fields" ,null));
    eventRegistry=GenUtil.uncheckedCast(context.get("Event Registry",null));
    ...
    }
източник
Translate

Първият непроверен глас може да бъде елиминиран чрез дефиниране на негенеричен клас, който разширява родовияMap<String, Pair<String, Boolean>>и съхраняване на това вSharedContextвместо родовоTreeMap, напрКарта за препращанеотГуава):

class InputFieldMap extends ForwardingMap<String,Pair<String,Boolean>> {

    private final Map<String,Pair<String,Boolean>> delegate =
        Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
    protected Map<String,Pair<String,Boolean>> delegate() { return delegate; }

}

// ...

context.set("Input Fields"  ,Collections.synchronizedMap(new InputFieldMap()));

// ...

inputFields     =(InputFieldMap)context.get("Input Fields"  ,null);
outputFields    =(Map<?,?>     )context.get("Output Fields" ,null);

Можете да направите втория глас безопасен по същия начин или (ако приемете, че четете само картата, без да я променяте) да използвате картата такава, каквато е (с заместващи параметри) и да конвертирате стойността в низ при всяко търсене:

String bar = String.valueOf(outputFields.get("foo"));

или увийте картата:

Map<?, String> wrappedOutputFields    =
    Maps.transformValues(outputFields, Functions.toStringFunction());

// ...

String bar = wrappedOutputFields.get("foo");
източник
Translate

Обектът SharedContext е този, който сте написали? Ако е така, възможно ли е да се замени общото String-> Object mapping със специфични полета?

напр.

context.setInputFields(...)
context.setOutputFields(...)
context.setEventRegistry(...)
context.getInputFields()
etc.

Общият контекстен обект за задържане винаги ми се струва не толкова перфектно решение. Особено с генеричните лекарства и непроверените гласови съобщения, които се получават.

Като алтернатива можете да създадете обект на обвивка, наречен SoftwareMonkeyContext, който има специфичните методи за задаване / получаване, както по-горе, и вътрешно използва вашия метод GenUtil.un проверенCast. Това би предотвратило необходимостта от използване на GenUtil.unckedCast на множество места във вашия код.

източник
Translate

Как еcontextпроменлива се присвоява? Дали е от параметъра ctx, който е от тип:

SharedContext<Object>

?

Ако е така, това е вашият проблем, защото когато правите извличане, не сте въвели ефективно това, което получавате.

източник
Translate

Коя версия на компилатора използвате? С компилатора Java 6 (прозорци Sun JDK) не видях подробно предупреждение. Получавам предупредителна информация само когато използвам флаг „-Xlint: непроверено“.

Опитайте -Xlint: -непроверено и ни уведомете дали разрешава проблема ви. За повече информация относно флаговете,

http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html

източник
Leave a Reply
You must be logged in to post a answer.
За автора