У меня проблемы с получением правильного синтаксиса для универсального метода с несколькими подстановочными знаками
Прежде всего, мне нужны два разных подстановочных знака, потому что (хотя я видел, что «?» Можно использовать для обозначения двух разных типов), как компилятор узнает, когда я использую «?» неоднозначно в методе.
Итак, ниже у меня есть очень недопустимая версия, где я использую '*' в качестве второго подстановочного знака (есть ли какой-нибудь другой подстановочный знак, который я могу использовать ???)
Может показаться, что в методе есть ошибка программирования, но я могу создать тип 'T' из типа '*' (у меня есть конструкторы для этого - в основном, берется буфер протокола Google и создается «полноценный объект»). "из этого)
private <T, ? extends Database<*>, * extends GeneratedMessage> T getItem(String key, ? db, Hashtable<String, T> table, String message) throws GadsDataException {
T returnValue = table.get(key);
if (returnValue == null) {
* temp = null;
try {
temp = db.get(key);
}
catch (InvalidProtocolBufferException e) {
throw new GadsDataException( message + key + " and hit: ", e);
}
if (temp != null) {
returnValue = new T(temp);
table.put(key, returnValue);
}
}
return returnValue;
}
В отчаянии я попробовал версию без каких-либо подстановочных знаков (мне она не нравится, так как она не сохраняет отношения типов, как это делали первые). Но компилятор не слишком заинтересован в этом. Думаю, мне стоит взглянуть на «Трансформер», о котором упоминал другой плакат.
private <T, D, G> T getItem(String key, D db, Hashtable<String, T> table, String message) throws GadsDataException {
T returnValue = table.get(key);
if (returnValue == null) {
G temp = null;
try {
temp = db.get(key);
}
catch (InvalidProtocolBufferException e) {
throw new GadsDataException( message + key + " and hit: ", e);
}
if (temp != null) {
returnValue = new T(temp);
table.put(key, returnValue);
}
}
return returnValue;
}
Так что я все еще застрял на конструкторе (как указывали другие авторы). Я попытался сделать компилятор счастливым, создав «искусственный» базовый класс
/**
* This is created as a base class for all objects that can
* construct themselves from a Google Protocol Buffer with one
* parameter.
*
* This is just done for the sake of templatizing the methods
* inside of the GadsLite API
*
*/
public class ConstructorOneParameter {
ConstructorOneParameter(GeneratedMessage G) {
// don't actually do anything... the derived
// class does all the work
// We're doing this just to templatize the GadsLite methods
}
}
Тогда я использовал это для определения типа в шаблонном методе. Тем не менее, компилятор не был счастлив.
private <T extends ConstructorOneParameter, D extends Database<G>, G extends GeneratedMessage> T
getItem(String key, D db, Hashtable<String, T> table, String message) throws GadsDataException {
T returnValue = table.get(key);
if (returnValue == null) {
G temp = null;
try {
temp = db.get(key);
}
catch (InvalidProtocolBufferException e) {
throw new GadsDataException( message + key + " and hit: ", e);
}
if (temp != null) {
returnValue = new T(temp);
table.put(key, returnValue);
}
}
return returnValue;
}
Несколько человек предложили фабрику, поэтому я изменил строку «returnValue = new T (temp);» в "returnValue = MessageObjectFactory create (temp);" Тогда для завода у меня есть:
public class MessageObjectFactory {
public static <G extends GeneratedMessage, R extends Object> R create(G message) {
R returnValue = null;
if (message instanceof ArtccData.Artcc) {
returnValue = new Artcc((ArtccData.Artcc)message);
}
return returnValue;
}
}
Я просто делаю один тип сейчас в качестве доказательства концепции. К сожалению, несмотря на то, что все является подклассом Object, компилятор недоволен «returnValue = new Artcc (...« строка жаловаться »не может преобразовать Artcc в R.». Есть ли конкретный пример «Transformer Factory»?