Интерфейс Filer
public interface Filer
close у Writer или
OutputStream, используемого для записи содержимого файла. Различают три вида файлов: исходные файлы, файлы классов и вспомогательные файлы ресурсов. Существуют два особых поддерживаемых расположения (поддерева в логической файловой системе), в которые помещаются вновь созданные файлы: одно для новых исходных файлов, другое для новых файлов классов. (Например, они могут задаваться в командной строке инструмента с помощью флагов -s и -d.) Фактические расположения новых исходных файлов и новых файлов классов могут совпадать или различаться при конкретном запуске инструмента. Файлы ресурсов можно создавать в любом из этих расположений. Методы чтения и записи ресурсов принимают аргумент с относительным именем. Относительное имя — это ненулевой непустой набор сегментов пути, разделённых '/'; '.' и '..' являются недопустимыми сегментами пути. Допустимое относительное имя должно соответствовать правилу «path-rootless» из раздела 3.3 RFC 3986.
Методы создания файлов принимают переменное число аргументов, чтобы можно было передать исходные элементы в качестве подсказок для инфраструктуры инструмента, помогающих эффективнее управлять зависимостями. Исходными элементами являются классы, интерфейсы или пакеты (представляющие файлы package-info) либо модули (представляющие файлы module-info), побудившие обработчик аннотаций попытаться создать новый файл. Иными словами, предполагается, что исходные элементы имеют гранулярность единиц компиляции (раздел 7.3 JLS, 7.3), то есть гранулярность уровня файлов, а не более мелкую гранулярность, например уровня объявления метода или поля.
Например, если обработчик аннотаций пытается создать исходный файл
GeneratedFromUserSource в ответ на обработку
@Generate
public class UserSource {}
элемент типа для UserSource следует передать в качестве одного из аргументов вызова метода создания, например так:
filer.createSourceFile("GeneratedFromUserSource",
eltUtils.getTypeElement("UserSource"));
Если исходных элементов нет, передавать ничего не нужно. Эта информация может использоваться в инкрементальной среде для определения необходимости повторного запуска обработчиков или удаления сгенерированных файлов. Неинкрементальные среды могут игнорировать сведения об исходных элементах. Во время каждого запуска инструмента обработки аннотаций файл с заданным путём можно создать только один раз. Если этот файл уже существует до первой попытки его создания, его прежнее содержимое будет удалено. Любая последующая попытка создать тот же файл во время одного запуска приведёт к возникновению FilerException; то же произойдёт при попытке создать и файл класса, и исходный файл с одним и тем же именем типа или пакета. Считается, что начальные входные данные инструмента созданы в нулевом раунде; поэтому попытка создать исходный файл или файл класса, соответствующий одному из этих входных данных, приведёт к возникновению FilerException.
В целом обработчики не должны заведомо пытаться перезаписывать существующие файлы, созданные не каким-либо обработчиком.
Filer может отклонить попытку открыть файл, соответствующий существующему классу или интерфейсу, например java.lang.Object. Аналогично, вызывающая сторона инструмента обработки аннотаций не должна заведомо настраивать инструмент таким образом, чтобы обнаруженные обработчики пытались перезаписывать существующие файлы, созданные не ими.
Обработчики могут указать, что исходный файл или файл класса был сгенерирован, добавив аннотацию Generated, если среда настроена так, что этот класс или интерфейс доступен.
- Примечание к API:
- Некоторого эффекта перезаписи файла можно добиться с помощью шаблона проектирования в стиле декоратора. Вместо непосредственного изменения класса его проектируют так, чтобы либо его суперкласс генерировался при обработке аннотаций, либо при обработке аннотаций генерировались его подклассы. Если генерируются подклассы, родительский класс можно спроектировать так, чтобы он использовал фабрики вместо открытых конструкторов; тогда клиентам родительского класса будут предоставляться только экземпляры подклассов.
- С версии:
- 1.6
- Внешние спецификации
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
JavaFileObject |
createClassFile |
Создаёт новый файл класса и возвращает объект для записи в него. |
FileObject |
createResource |
Создаёт новый вспомогательный файл ресурсов для записи и возвращает объект файла для него. |
JavaFileObject |
createSourceFile |
Создаёт новый исходный файл и возвращает объект для записи в него. |
FileObject |
getResource |
Возвращает объект для чтения существующего ресурса. |
Подробное описание методов
createSourceFile
JavaFileObject createSourceFile(CharSequence name, Element... originatingElements) throws IOException
Исходный файл также можно создать для хранения сведений о пакете, включая аннотации пакета. Чтобы создать исходный файл для именованного пакета, укажите в аргументе name имя пакета, за которым следует ".package-info"; для создания исходного файла для безымянного пакета используйте "package-info".
Необязательное имя модуля добавляется перед именем типа или пакета и отделяется символом "/". Например, чтобы создать исходный файл для класса a.B в модуле foo, используйте аргумент name со значением "foo/a.B".
Если явный префикс модуля не задан, а среда поддерживает модули, подходящий модуль определяется автоматически. Если определить подходящий модуль не удаётся, возникает исключение FilerException. При определении реализация может использовать сведения о конфигурации инструмента обработки аннотаций.
Создание исходного файла в безымянном пакете или для безымянного пакета в именованном модуле не поддерживается.
Если среда настроена на поддержку неявно объявленных классов, аргумент name используется для задания начального компонента имени выходного файла. Например, filer.createSourceFile("Foo") — для создания неявно объявленного класса, размещённого в Foo.java. Все неявно объявленные классы должны находиться в безымянном пакете.
- Примечание к API:
- Чтобы использовать для кодирования содержимого файла определённую кодировку, можно создать
OutputStreamWriterс выбранной кодировкой на основеOutputStreamвозвращённого объекта. Если для записи непосредственно используетсяWriterвозвращённого объекта, его кодировка определяется реализацией. Инструмент обработки аннотаций может иметь флаг-encodingили аналогичный параметр для указания кодировки; в противном случае обычно используется кодировка платформы по умолчанию.Чтобы избежать последующих ошибок, содержимое исходного файла должно быть совместимо с версией исходного кода, используемой при этом запуске.
- Примечание по реализации:
- В эталонной реализации, если инструмент обработки аннотаций обрабатывает один модуль M, то M используется в качестве модуля для файлов, созданных без явного префикса модуля. Если инструмент обрабатывает несколько модулей и
Elements.getPackageElement(package-of(name))возвращает пакет, в качестве целевого используется модуль, которому принадлежит возвращённый пакет. Если целевой модуль нельзя определить по приведённым выше правилам, для его указания можно использовать отдельный параметр. - Параметры:
-
name— каноническое (полностью квалифицированное) имя главного класса или интерфейса, объявляемого в этом файле, либо имя пакета, за которым следует".package-info", для файла сведений о пакете -
originatingElements— классы, интерфейсы, пакеты или модули, причинно связанные с созданием этого файла; аргумент можно опустить илиnull - Возвращает:
- объект
JavaFileObjectдля записи нового исходного файла - Вызывает исключение:
-
FilerException— если файл с таким путём уже был создан, если тот же класс или интерфейс уже был создан, если имя недопустимо для создаваемого элемента, если не удаётся определить целевой модуль, если целевой модуль недоступен для записи или если модуль указан, а среда не поддерживает модули -
IOException— если файл не удаётся создать - См. Спецификацию языка Java:
- 7.3 Единицы компиляции
createClassFile
JavaFileObject createClassFile(CharSequence name, Element... originatingElements) throws IOException
Файл класса также можно создать для хранения сведений о пакете, включая аннотации пакета. Чтобы создать файл класса для именованного пакета, укажите в аргументе name имя пакета, за которым следует ".package-info"; создание файла класса для безымянного пакета не поддерживается.
Необязательное имя модуля добавляется перед именем типа или пакета и отделяется символом "/". Например, чтобы создать файл класса для класса a.B в модуле foo, используйте аргумент name со значением "foo/a.B".
Если явный префикс модуля не задан, а среда поддерживает модули, подходящий модуль определяется автоматически. Если определить подходящий модуль не удаётся, возникает исключение FilerException. При определении реализация может использовать сведения о конфигурации инструмента обработки аннотаций.
Создание файла класса в безымянном пакете или для безымянного пакета в именованном модуле не поддерживается.
Если среда настроена на поддержку неявно объявленных классов, аргумент name используется для задания начального компонента имени выходного файла. Например, filer.createSourceFile("Foo") — для создания неявно объявленного класса, размещённого в Foo.java. Все неявно объявленные классы должны находиться в безымянном пакете.
- Примечание к API:
- Чтобы избежать последующих ошибок, содержимое файла класса должно быть совместимо с версией исходного кода, используемой при этом запуске.
- Примечание по реализации:
- В эталонной реализации, если инструмент обработки аннотаций обрабатывает один модуль M, то M используется в качестве модуля для файлов, созданных без явного префикса модуля. Если инструмент обрабатывает несколько модулей и
Elements.getPackageElement(package-of(name))возвращает пакет, в качестве целевого используется модуль, которому принадлежит возвращённый пакет. Если целевой модуль нельзя определить по приведённым выше правилам, для его указания можно использовать отдельный параметр. - Параметры:
-
name— двоичное имя записываемого класса или интерфейса либо имя пакета, за которым следует".package-info", для файла сведений о пакете -
originatingElements— классы, интерфейсы, пакеты или модули, причинно связанные с созданием этого файла; аргумент можно опустить илиnull - Возвращает:
- объект
JavaFileObjectдля записи нового файла класса - Вызывает исключение:
-
FilerException— если файл с таким путём уже был создан, если тот же класс или интерфейс уже был создан, если имя недопустимо для класса или интерфейса, если не удаётся определить целевой модуль, если целевой модуль недоступен для записи или если модуль указан, а среда не поддерживает модули -
IOException— если файл не удаётся создать
createResource
FileObject createResource(JavaFileManager.Location location, CharSequence moduleAndPkg, CharSequence relativeName, Element... originatingElements) throws IOException
CLASS_OUTPUT и SOURCE_OUTPUT. Имя ресурса может задаваться относительно какого-либо модуля и/или пакета (как для исходных файлов и файлов классов), а затем — относительно пути. В упрощённом смысле полный путь нового файла будет конкатенацией location, moduleAndPkg и relativeName. Если moduleAndPkg содержит символ "/", префикс до символа "/" является именем модуля, а суффикс после символа "/" — именем пакета. Суффикс пакета может быть пустым. Если moduleAndPkg не содержит символ "/", весь аргумент интерпретируется как имя пакета. Если заданное расположение не является ни расположением с поддержкой модулей, ни выходным расположением, содержащим несколько модулей, а явный префикс модуля указан, возникает исключение FilerException.
Если заданное расположение является расположением с поддержкой модулей или выходным расположением, содержащим несколько модулей, и явный префикс модуля не указан, подходящий модуль определяется автоматически. Если определить подходящий модуль не удаётся, возникает исключение FilerException. При определении реализация может использовать сведения о конфигурации инструмента обработки аннотаций.
Файлы, созданные этим методом, не регистрируются для обработки аннотаций, даже если полный путь файла совпадает с полным путём нового исходного файла или нового файла класса.
- Примечание по реализации:
- В эталонной реализации, если инструмент обработки аннотаций обрабатывает один модуль M, то M используется в качестве модуля для файлов, созданных без явного префикса модуля. Если инструмент обрабатывает несколько модулей и
Elements.getPackageElement(package-of(name))возвращает пакет, в качестве целевого используется модуль, которому принадлежит возвращённый пакет. Если целевой модуль нельзя определить по приведённым выше правилам, для его указания можно использовать отдельный параметр. - Параметры:
-
location— расположение нового файла -
moduleAndPkg— модуль и/или пакет, относительно которого следует задать имя файла, либо пустая строка, если их нет -
relativeName— заключительные компоненты пути файла -
originatingElements— классы, интерфейсы, пакеты или модули, причинно связанные с созданием этого файла; аргумент можно опустить илиnull - Возвращает:
- объект
FileObjectдля записи нового ресурса - Вызывает исключение:
-
IOException— если файл не удаётся создать -
FilerException— если файл с таким путём уже был создан, если не удаётся определить целевой модуль, если целевой модуль недоступен для записи либо если указан явный целевой модуль, а расположение его не поддерживает -
IllegalArgumentException— для неподдерживаемого расположения -
IllegalArgumentException— еслиmoduleAndPkgимеет неверный формат -
IllegalArgumentException— еслиrelativeNameне является относительным
getResource
FileObject getResource(JavaFileManager.Location location, CharSequence moduleAndPkg, CharSequence relativeName) throws IOException
CLASS_OUTPUT и SOURCE_OUTPUT. Если moduleAndPkg содержит символ "/", префикс до символа "/" является именем модуля, а суффикс после символа "/" — именем пакета. Суффикс пакета может быть пустым; однако, если имя модуля указано, оно должно быть непустым. Если moduleAndPkg не содержит символ "/", весь аргумент интерпретируется как имя пакета.
Если заданное расположение не является ни расположением с поддержкой модулей, ни выходным расположением, содержащим несколько модулей, а явный префикс модуля указан, возникает исключение FilerException.
Если заданное расположение является расположением с поддержкой модулей или выходным расположением, содержащим несколько модулей, и явный префикс модуля не указан, подходящий модуль определяется автоматически. Если определить подходящий модуль не удаётся, возникает исключение FilerException. При определении реализация может использовать сведения о конфигурации инструмента обработки аннотаций.
- Примечание по реализации:
- В эталонной реализации, если инструмент обработки аннотаций обрабатывает один модуль M, то M используется в качестве модуля для файлов, читаемых без явного префикса модуля. Если инструмент обрабатывает несколько модулей и
Elements.getPackageElement(package-of(name))возвращает пакет, в качестве исходного используется модуль, которому принадлежит возвращённый пакет. Если целевой модуль нельзя определить по приведённым выше правилам, для его указания можно использовать отдельный параметр. - Параметры:
-
location— расположение файла -
moduleAndPkg— модуль и/или пакет, относительно которого следует искать файл, либо пустая строка, если их нет -
relativeName— заключительные компоненты пути файла - Возвращает:
- объект для чтения файла
- Вызывает исключение:
-
FilerException— если файл с таким путём уже открыт для записи, если не удаётся определить исходный модуль, если целевой модуль недоступен для записи либо если указан явный целевой модуль, а расположение его не поддерживает -
IOException— если файл не удаётся открыть -
IllegalArgumentException— для неподдерживаемого расположения -
IllegalArgumentException— еслиmoduleAndPkgимеет неверный формат -
IllegalArgumentException— еслиrelativeNameне является относительным
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/25/docs/api/java.compiler/javax/annotation/processing/Filer.html