Как написать общий метод в Java.Как написать общий метод в Java
В C# я хотел бы сделать это
public static T Resolve<T>()
{
return (T) new object();
}
Что эквивалент в Java?
Как написать общий метод в Java.Как написать общий метод в Java
В C# я хотел бы сделать это
public static T Resolve<T>()
{
return (T) new object();
}
Что эквивалент в Java?
Во-первых, ваш пример C# неверен; он будет бросать InvalidCastException
, если только typeof(T) == typeof(object)
. Вы можете это исправить, добавив constraint:
public static T Resolve<T>() where T : new() {
return new T();
}
Теперь, это было бы равнозначно синтаксис в Java (или, по крайней мере, так близко, как мы можем получить):
public static <T> T Resolve() {
return (T) new T();
}
Обратите внимание на двойной упоминание о T
в декларации: один - это T
в <T>
, который параметризует метод, а второй - тип возврата T
.
К сожалению, приведенное выше не работает на Java. Из-за того, как внедрены генерические средства Java, информация о времени выполнения около T
недоступна, и поэтому приведенное выше дает ошибку времени компиляции. Теперь, вы можете обойти это ограничение, так как:
public static <T> T Resolve(Class<T> c) {
return c.newInstance();
}
Обратите внимание на необходимость принятия в T.class
. Это называется runtime type token. Это идиоматический способ справиться с этой ситуацией.
Это будет исключать некоторые исключения! Не используйте отражение в этих случаях. –
@tackline: Нет, это идиоматическая Java для обработки этой ситуации: ср. http://java.sun.com/docs/books/tutorial/extra/generics/literals.html – jason
«Во-первых, ваш пример C# неверен». Я не думаю, что для метода было исключено исключение в определенных ситуациях (пример OP) (особенно в вопросе о синтаксисе). Однако я считаю, что метод не компилируется (ваш пример C#). Вы забыли '
Попробуйте http://java.sun.com/docs/books/tutorial/extra/generics/methods.html
public static <T> T Resolve()
{
return (T) new Object();
}
Будьте осторожны (T)
, но я не уверен, что это правильно. Я знаю, что общий ролик вызывает множество проблем. Я уже провел с ним много времени ...
Не будет ли этот код бросить 'java.lang.ClassCastException'? – missingfaktor
Это нормально работает в Java, потому что T во время компиляции стирается до Object. Однако вы действительно не получаете никакой безопасности типов от этой реализации. –
@ GreyMatter 9: Правильно, метод Resolve вызывает java.lang.ClassCastException, если T - любой другой тип, кроме java.lang.Object. –
Как и другие комментаторы отметили, вы можете сделать это с помощью Java, а также - с такой большой возможности создать исключение произнесения во время выполнения:
@SuppressWarnings("unchecked")
public static <T> T resolve() {
return (T) new Object();
}
Если вы не используете @SuppressWarnings
аннотацию, однако, Java тип erasure вступает в игру, и вы получите предупреждение о компиляторе. Исключение будет также происходить где-то еще: если вы пытаетесь его использовать:
String s = <String>resolve();
будет исключать.
С другой стороны, вы, вероятно, хотели бы использовать new T()
в C#. Это невозможно сделать на Java. Предлагаемое обходное решение заключается в использовании Class<T>
в качестве параметра типа, если вам нужно полагаться на информацию о типе во время выполнения.Для примера, это будет означать, что вы должны реорганизовать его в этой версии:
public static <T> T resolve(Class<T> type) {
try {
return type.newInstance();
} catch(Exception e) {
// deal with the exceptions that can happen if
// the type doesn't have a public default constructor
// (something you could write as where T : new() in C#)
}
}
Кстати, вы можете использовать это также, чтобы избавиться от предупреждения в предыдущем случае, и поместить исключение во время выполнения в более чувствительная линия:
public static <T> T resolve(Class<T> type) {
return type.cast(new Object());
}
Этот фрагмент кода будет вести себя так же, как тот, который вы дали в качестве примера - в том числе исключение, которое происходит, когда T
любого типа отличается от Object
.
Вы хотите какой-то фабрики:
public interface MyFactory<T> {
T newInstance();
}
Затем, которые могут быть переданы в где это необходимо. В вашем коде:
public static T resolve<T>(MyFactory<T> factory) {
return factory.newInstance();
}
Примечание: нет абсолютно никаких оснований для использования отражения для этого !!
Как новый текст написан внутри MyFactory
Scratch этот вопрос. Я вижу, что тип класса java (java.lang.Class) имеет метод newInstance() для генерации нового экземпляра, где есть конструктор без параметров. – Lisa
@Lisa Вы действительно не хотите, чтобы прикоснуться к отражению, если вы можете помочь. Реализации 'MyFactory' могут построить определенный' T' по своему усмотрению. –
Ваш код C# вызывает InvalidCastException, если 'T' не является' объектом'. – dtb
ваш общий метод C# не является хорошим примером, так как для почти любого значения T, которое бросает бросок. –