Как упомянул @MebinJoe, это была проблема с чванством. Не удалось решить проблему с Swagger, но в итоге использовал Postman для тестирования вышеуказанного кода. Несколько файлов были успешно прикреплены и отправлены по электронной почте.
Короткий ответ: Java и C# не избегают раздельной компиляции; они полностью используют его.
То, где они отличаются, - то, что они не требуют, чтобы программист записал пару отдельных файлов заголовка/реализации при записи допускающей повторное использование библиотеки. Пользователь пишет определение класса однажды, и компилятор извлекает информацию, эквивалентную "заголовку" из того единственного определения, и включает его в выходной файл как "метаданные типа". Так выходной файл (a .jar
полный .class
файлы в Java, или .dll
блок на основанных на.NET языках), комбинация двоичных файлов И заголовков в единственном пакете.
Затем, когда другой класс компилируется, и он зависит от первого класса, он может посмотреть на метаданные вместо того, чтобы иметь необходимость найти, что отдельное включает файл.
Это происходит, что они предназначаются для виртуальной машины, а не определенной архитектуры кристалла, но это - отдельный вопрос; они могли вставить машинный код для процессоров типа x86 как двоичный файл и все еще иметь подобные заголовку метаданные в том же файле также (это - на самом деле опция в.NET, хотя редко используется).
В компиляторах C++ распространено попытаться ускорить компиляцию при помощи "предварительно скомпилированных заголовков". Метаданные в.NET .dll
и .class
файлы во многом как предварительно скомпилированный заголовок - уже проанализированы и индексируемы, готовы к быстрым поискам.
Результат - то, что на этих современных языках, существует один способ сделать модуляризацию, и это имеет характеристики отлично организованного и оптимизированного рукой C++ модульная система сборки - довольно изящный, говоря ASFAC ++ B.
IMO, один из самых больших факторов здесь - то, что и Java и.NET используют промежуточные языки; это означает, что скомпилированная единица (банка/блок) содержит, как предпосылка, много выразительных метаданных о типах, методах, и т.д.; подразумевать, что это уже размечается удобно для ссылочной проверки. Время выполнения все еще проверяет так или иначе, в случае, если Вы вытягиваете быстрый;-p
Это очень далеко не удалено из MIDL, который подкрепляет COM, хотя там TLB часто является отдельным объектом.
Если я неправильно понял Ваше значение, сообщите мне...
Вы могли считать Java .class файлом, чтобы быть подобными предварительно скомпилированному заголовочному файлу в C/C++. По существу .class файл является промежуточной формой, в которой нуждался бы компоновщик C/C++, а также вся информация, содержавшаяся в заголовке (Java просто не имеет отдельного заголовка).
Сформируйте свой комментарий в другом сообщении:
"Я в основном имею в виду идею в C/C++, что каждый исходный файл является своей собственной отдельной единицей компиляции. Это, как очень кажется, не имеет место в C# или Java".
В Java (я не могу говорить за C#, но я предполагаю, что это - то же), каждый исходный файл является своей собственной отдельной единицей компиляции. Я не уверен, почему Вы думали бы, что это не..., возможно, у нас есть различные определения единицы компиляции?
Требуется некоторая поддержка языка (иначе, компиляторы C/C++ сделали бы это также),
В частности, это требует, чтобы компилятор генерировал автономные модули, которые выставляют метаданные, на которые другие модули могут сослаться для вызова в них.
Блоки.NET являются простым примером. Все файлы в проекте компилируются вместе, генерируя один dll. Этот dll может быть запрошен.NET для определения, какие типы это содержит, так, чтобы другие блоки могли назвать функции, определяемые в нем.
И использовать это, должно быть законно на языке сослаться на другие модули.
В C++, что определяет границу модуля? Язык указывает, что компилятор только рассматривает данные в своей текущей единице компиляции (.cpp файл + включенные заголовки). Нет никакого механизма для определения, "я хотел бы вызвать функцию Foo в Панели модуля, даже при том, что у меня нет прототипа или чего-либо для него во время компиляции". Единственный механизм, который Вы имеете для того, чтобы поделиться информацией типа между файлами, с #includes.
Существует предложение добавить систему модуля к C++, но это не будет в C++ 0x. В последний раз я видел, план состоял в том, чтобы рассмотреть это для TR1 после того, как 0x отсутствует.
(Стоит упомянуть, что #include система в C/C++ первоначально использовалась, потому что это ускорит компиляцию. Назад в 70-х, это позволило компилятору обрабатывать код на простом линейном сканировании. Это не должно было создавать синтаксические деревья или другие такие "усовершенствованные" функции. Сегодня, таблицы повернулись, и это стало огромным узким местом, и с точки зрения удобства использования и с точки зрения скорости компиляции.)
Объектные файлы, сгенерированные C/C++, являются ment, чтобы быть только для чтения компоновщиком, не компилятором.
Относительно других языков: Turbo Pascal IIRC имел "единицы", которые Вы могли использовать, не имея никакого исходного кода. Я думаю, что точка должна создать метаданные наряду со скомпилированным кодом, который может затем использоваться компилятором для выяснения интерфейса к модулю (т.е. подписи функций, расположение класса и т.д.)
Одной проблемой с C/C++, который предотвращает просто замену #include с некоторым #import, является также препроцессор, который может полностью измениться, значение/синтаксис и т.д. включало/импортировало модули. Это было бы очень трудно (если не невозможный) с подобной Java системой модуля.