2013-11-27 3 views
1

У меня есть метод, который я хочу, чтобы реорганизовать, и она выглядит (ну, очень упрощенно), как это:Как предотвратить стирание стилей?

import com.sun.tools.javac.util.Pair; 

private int foo(Pair<String, ?>... params) { 
    if (params[0].snd instanceof String) { 
     // do something 
     return 0; 
    } else if (params[0].snd instanceof ArrayList) { 
     // do something else 
     return 1; 
    } 
    return -1; // realistically in the code base, this line will never happen **edit: disregard this line 
} 

так я думал, я хотел бы сделать что-то вроде разделить его на два метода, так что Мне не нужно проверять тип. (Это даже хорошо рефакторинг?)

, так что я хотел сделать что-то вроде этого:

private int foo(Pair<String, String>... params) { 
    // do something 
    return 0; 
} 

private int foo(Pair<String, ArrayList>... params) { 
    // do something else 
    return 1; 
} 

Но компилятор продолжает говорить мне, что оба foo() методы имеют один и тот же тип стирания. Ява просто стирает все, что знает Pair<A, B>? Если да, то какой способ лучше реорганизовать? (или нужен рефакторинг)

+2

Я бы использовал ваш первый метод. Однако я бы заменил 'return -1;' на 'throw new IllegalArgumentsException (« message »);' – Cruncher

ответ

5

Во время компиляции Java будет erase информацию о типе информации Generics. Невозможно предотвратить это. Во время выполнения пара не имеет <A,B> эффективно <Object,Object>.

Что касается рефакторинга, есть несколько вещей, которые вы можете предпочесть (но, кроме одной рекомендации), в вашем примере не так много улучшений - я бы, вероятно, использовал одно другое (если эта последняя строка может " т случиться. И я хотел бы использовать список вместо конкретного типа List.

private int foo(Pair<String, ?>... params) { 
    if (params[0].snd instanceof String) { 
    return 0; 
    } else { //if(params[0].snd instanceof List) { //is a List interface, not which List 
    // do something else 
    return 1; 
    } 
// return -1; // If it can't happen, why have it here. 
} 
+1

Ну, не существует 'Pair '. После стирания есть только «Пара». –

+0

@RohitJain True. Добавлено эффективно, чтобы уточнить. –

+0

@ElliottFrisch есть ли у вас какие-либо предложения по реорганизации метода, который я опубликовал? –

1

Я хотел бы добавить, что

private int foo(Pair<String, String>... params) { 
    return 0; 
} 

private int foo(Pair<String, ArrayList>... params) { 
    return 1; 
} 

, если этот код было разрешено, то не было бы много пользы. Вы знаете, какой тип вы переходите в foo. Это какой бы тип ссылки не был, а не тип a ctual object. Поэтому просто замените все вызовы на это, где вы пройдете Pair<String, String> с помощью только 0.

То есть, этот метод называется определяемым во время компиляции. Не во время выполнения. И если это определяется во время компиляции, вам не нужно вообще вызывать метод.

+0

О, извините, я спрятал много деталей из кода, чтобы заставить его сказать 'return 0'. –

+0

@DavidT. Ах хорошо. Для меня это выглядело так, что цель метода заключалась в определении того, было ли что-то «Пара» 'или' Pair ' – Cruncher

+0

не беспокоиться, что вы сказали, учитывая мою ошибку. +1 upvote. –

Смежные вопросы