Этот ответ должен быть довольно коротким и сладким, чтобы ответить (часть) озаглавленного вопроса. Если вы хотите получить более подробный ответ, объясняющий, почему вы должны их там поместить, пожалуйста, перейдите здесь .
Общее правило для размещения typename
в основном, когда вы используете параметр шаблона, и хотите получить доступ к вложенному typedef
или с использованием псевдонима, например:
template
struct test {
using type = T; // no typename required
using underlying_type = typename T::type // typename required
};
Обратите внимание, что это также относится к метафункциям или вещи, которые также принимают общие параметры шаблона. Однако, если предоставленный параметр шаблона является явным типом, вам не нужно указывать typename
, например:
template
struct test {
// typename required
using type = typename std::conditional::type;
// no typename required
using integer = std::conditional::type;
};
Общие правила добавления определителя template
в основном аналогичны, за исключением они обычно включают шаблонные функции-члены (статические или другие) структуры / класса, которые сами шаблоны, например:
Учитывая эту структуру и функцию:
template
struct test {
template
void get() const {
std::cout << "get\n";
}
};
template
void func(const test& t) {
t.get(); // error
}
Попытка доступа t.get
изнутри функции приведет к ошибке:
main.cpp:13:11: error: expected primary-expression before 'int'
t.get();
^
main.cpp:13:11: error: expected ';' before 'int'
Таким образом, в этом контексте вам понадобится ключевое слово template
заранее и вызвать его так:
t.template get
Таким образом, компилятор будет анализировать это правильно, а не t.get < int
.
Для Java 7 и выше должна использоваться попытка с ресурсами :
try (InputStream in = new FileInputStream(file)) {
// TODO: work
} catch (IOException e) {
// TODO: handle error
}
, Если Вы застреваете на Java 6 или ниже...
Этот шаблон старается не слоняться без дела с [1 111] пустой указатель :
try {
InputStream in = new FileInputStream(file);
try {
// TODO: work
} finally {
in.close();
}
} catch (IOException e) {
// TODO: error handling
}
<час> Для большего количества детали о том, как эффективно иметь дело с близкий , считайте это сообщение в блоге: Java: как не сделать путаницу потока, обрабатывающего . Это имеет более пример кода, больше глубины и покрывает ловушки обертывания близкий в выгода блок.
Что-то как следующее должно сделать это до Вас, бросаете ли Вы или глотаете IOException при попытке закрыть поток.
FileInputStream fis = null;
try
{
fis = new FileInputStream(file);
... process ...
}
catch (IOException e)
{
... blah blah blah ...
}
finally
{
try
{
if (fis != null)
fis.close();
}
catch (IOException e)
{
}
}
Вы могли также использовать простой статический Вспомогательный метод:
public static void closeQuietly(InputStream s) {
if (null == s) {
return;
}
try {
s.close();
} catch (IOException ioe) {
//ignore exception
}
}
и использование это от Вашего наконец блок.
Ничего особенного для добавления, за исключением очень незначительного стилистического предложения. канонический пример сам документирующий код применяется в этом случае - дают описательное имя переменной проигнорированному IOException
, что необходимо уловить смысл close()
.
, Таким образом, ответ squiddle становится:
public static void closeQuietly(InputStream s) {
try {
s.close();
} catch (IOException ignored) {
}
}
В большинстве случаев я нахожу, что это просто лучше не , чтобы поймать исключения IO, и просто использовать попытку наконец:
final InputStream is = ... // (assuming some construction that can't return null)
try {
// process is
...
} finally {
is.close();
}
За исключением FileNotFoundException
, Вы обычно не можете "работать вокруг" IOException
. Единственная вещь, оставленная сделать, сообщить об ошибке, и Вы будете обычно обрабатывать это далее стек вызовов, таким образом, я найду, что он лучше распространяет исключение.
С тех пор IOException
контролируемая исключительная ситуация, необходимо будет объявить что этот код (и любой из его клиентов) throws IOException
. Это могло бы быть слишком шумным, или Вы не могли бы хотеть показывать деталь реализации использования IO. В этом случае можно обернуть весь блок с обработчиком исключений, который переносится IOException
в RuntimeException
или абстрактный тип исключительной ситуации.
Деталь: я знаю, что вышеупомянутый код глотает любое исключение из try
блок, когда close
операция в finally
блок производит IOException
. Я не думаю, что это - большая проблема: обычно, исключение из try
блок будет тем же IOException
, который заставляет close
перестать работать (т.е. довольно редко для IO хорошо работать и затем перестать работать при закрытии). Если это - беспокойство, это могло бы стоить проблемы для "заставления завершения замолчать".
Надо надеяться, мы получим закрытия в Java однажды, и затем мы потеряем много многословия.
Так вместо этого будет вспомогательный метод где-нибудь в javaIO, что можно импортировать, это будет, вероятно, брать интерфейс "Closable" и также блок. В том вспомогательном методе попытка {closable.close ()} выгода (IOException исключая) {//вздор} определяется раз и навсегда, и затем Вы будете в состоянии записать
Inputstream s = ....;
withClosable(s) {
//your code here
}
Вы заинтересованы, прежде всего, с получением чистого отчета от FindBugs или с наличием кода, который работает? Это не обязательно то же самое. Ваш исходный код прекрасен (хотя я избавился бы от избыточного if (fis != null)
, проверка начиная с OutOfMemoryException
будет брошена иначе). FileInputStream имеет метод финализатора, который закроет поток для Вас в маловероятном случае, что Вы на самом деле получаете IOException в своей обработке. Это просто не стоит беспокойства создания Вашего кода, более сложного для предотвращения крайне маловероятного сценария
Редактирование: , если Вы получаете столько IOExceptions, что Вы сталкиваетесь с проблемами с очередью финализатора тогда, у Вас есть далеко далекая важная персона для жарки! Это о получении чувства перспективы.