source
- это внутренняя команда оболочки (см., например, Bash Builtin Commands ), а не внешнюю программу, которую вы можете запустить. В вашей системе нет исполняемого файла с именем source
, поэтому вы получаете ошибку No such file or directory
.
Вместо модуля command
используйте shell
, который будет выполнять source
внутри оболочки.
В цикле with_items
Ansible будет запускать оболочку дважды, и оба процесса будут независимы от каждого Другие. Переменные, установленные в одном, не будут отображаться другим.
Вы должны запустить две команды в одном процессе оболочки, например, с помощью:
- name: Install node {{ nvm.node_version }}
shell: "source /home/centos/.nvm/nvm.sh && nvm install {{ nvm.node_version }}"
tags: nvm
Используйте {{ ansible_env.HOME }}
вместо ~
в задаче git
. Любой из них будет работать здесь, но расширение тильды - это функциональность оболочки, и вы пишете код для Ansible.
Я использовал аналогичное решение для того, что он объясняет здесь для нескольких проектов, и нашел, что это очень полезно.
http://blog.xebia.com/2009/02/07 / acessing-generic-types-at-runtime-in-java /
Суть его заключается в следующем:
public Class returnedClass() {
ParameterizedType parameterizedType = (ParameterizedType)getClass()
.getGenericSuperclass();
return (Class) parameterizedType.getActualTypeArguments()[0];
}
Я согласен с Visage. Генерики предназначены для проверки времени компиляции, а не для динамического набора времени выполнения. Похоже на то, что вам нужно, это просто фабричная модель. Но если ваше «делать это» не является инстанцированием, то, скорее всего, будет работать простой Enum. Как и то, что сказал Майкл, если у вас есть немного более конкретный пример, вы получите лучшие ответы.
В отличие от .NET Java generics реализуются методом, называемым стиранием типа.
. Это означает, что компилятор будет использовать информацию о типе при создании файлов классов, но не передавать это информацию в байтовый код. Если вы посмотрите на скомпилированные классы с помощью javap или аналогичных инструментов, вы обнаружите, что List<String>
является простым List
(Object
) в файле класса, как это было в коде pre-Java-5.
. Кодирование, получающее общий список, будет «перезаписано» компилятором, чтобы включить в него броски, которые вам придется писать в более ранних версиях. По сути, следующие два фрагмента кода идентичны с точки зрения байтового кода после компилятора с ними:
Java 5:
List<String> stringList = new ArrayList<String>();
stringList.add("Hello World");
String hw = stringList.get(0);
Java 1.4 и до:
List stringList = new ArrayList();
stringList.add("Hello World");
String hw = (String)stringList.get(0);
При чтении значений из общего класса в Java 5 автоматически добавляется необходимый приведение к объявленному параметру типа. При вставке компилятор проверяет значение, которое вы пытаетесь ввести и прервите с ошибкой, если это не строка.
Все дело в том, чтобы сохранить старые библиотеки и новый расширенный код в интероперабельности без какой-либо необходимости перекомпилировать существующие библиотеки. Это основное преимущество над способом .NET, когда родовые классы и не общие игры живут бок о бок, но не могут быть взаимозаменяемы.
Оба подхода имеют свои плюсы и минусы, но так оно и есть находится в Java.
Чтобы вернуться к исходному вопросу: вы не сможете получить информацию о типе во время выполнения, потому что его просто больше нет, как только компилятор выполнил свою работу. Это, безусловно, ограничивает в некотором роде и есть некоторые капризные способы вокруг него, которые обычно основаны на хранении экземпляра класса где-то, но это не стандартная функция.
Проблема заключается в том, что большинство обобщающих материалов исчезнет во время компиляции.
Одним из распространенных решений является сохранение типа во время создания объекта.
Для краткого введения в поведение типа Erasure java прочтите эту страницу
Похоже, что вы хотите на самом деле не общий класс, а интерфейс с множеством различных реализаций. Но, возможно, это станет понятнее, если вы изложите свою конкретную конкретную цель.
Из-за стирания типа , нет никакого способа сделать это напрямую. Тем не менее, вы можете сделать Class<T>
в конструкторе и удерживать его внутри вашего класса. Затем вы можете проверить его на три возможных типа Class
, которые вы разрешаете.
Однако, если есть только три возможных типа, вы можете рассмотреть рефакторинг в enum вместо этого.
Вся точка родового класса состоит в том, что вам не нужно знать тип, который используется ...
Если вы знаете несколько конкретных типов, которые имеют смысл, вы должны создать подклассы вашего общего типа с реализацией.
Итак,
public class Foo<T>
public ???? Bar()
{
//else condition goes here
}
И затем
public class DateFoo extends Foo<Date>
public ???? Bar()
{
//Whatever you would have put in if(T == Date) would go here.
}
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
Вы уверены, что это работает? – Ram 12 May 2011 в 11:28