#java #url #new-operator
#java #url #new-оператор
Вопрос:
Я очень новичок в Java, просто пытаюсь запустить несколько простых программ. У меня есть этот код:
import java.net.*;
import java.io.*;
class example1 {
public static void main(String args[]){
try{
URL hp = new URL("http://www.java2s.com");
System.out.println("it all worked?");
}catch (MalformedURLException e){
System.err.println("New URL failed");
System.err.println("exception thrown: " e.getMessage());
}
System.out.println(hp.getProtocol());
}
}
Компилятор java «не может найти символ: hp», что заставило бы меня поверить, что объект url, hp, не создается строкой:
URL hp = new URL("http://www.java2s.com");
Но разве оператор catch не должен сообщать об ошибке?
Я попытался скомпилировать без блоков try-catch, но я получал сообщение об ошибке «незарегистрированное исключение MalformedURLException; должно быть перехвачено или объявлено выброшенным»
Если я удалю последнюю строку, которая ссылается на hp, программа компилируется и запускается, но просто отображает «все сработало?».
Я уверен, что здесь есть простое объяснение, но я не очень разбираюсь в Java. Спасибо
Ответ №1:
Другие ответы дали вам несколько полезных советов, как избежать ошибки. Но я хотел бы попытаться объяснить, как ваше понимание того, что означает ошибка, запутано.
Эта строка:
URL hp = new URL("http://www.java2s.com");
выполняет две вещи одновременно. Он объявляет переменную (которая в более общем случае называется компилятором «символом») с именем hp
, которая может указывать на экземпляр URL; и он создает экземпляр URL и hp
указывает на него.
Вы интерпретировали ошибку как «объект url hp не создается». Итак, прежде всего, hp
это не объект — это в лучшем случае ссылка на объект, и, конечно, это также может быть null
, и в этом случае это ссылка на ничто. Но символ hp
существует в пределах его объявления, независимо от того, назначена ли ему ссылка на объект.
Если создание объекта завершилось неудачно, то new URL ...
есть часть инструкции завершилась неудачно, тогда, скорее всего, произошло бы исключение, как вы и ожидали. Но даже если по какой-то неясной причине создание завершилось неудачно, но не выдало исключение, вероятным результатом будет то, что hp
будет null
, и в этом случае допустимая попытка разыменования переменной hp
приведет к a NullPointerException
.
Все это просто для иллюстрации того, что полученная вами ошибка не имеет ничего общего с тем, было ли hp
присвоено значение, и просто указывает, что hp
оно не было объявлено в области, в которой вы пытаетесь его использовать.
Проблема в том, что try
блок создает свою собственную область видимости, поэтому переменные, объявленные в нем, недоступны за пределами блока. Вы получите точно такую же ошибку, если первая строка внутри вашего try
блока будет прочитана просто URL hp;
. Как показано в других ответах, решение этой проблемы заключается в объявлении hp
вне try
блока, чтобы более поздняя ссылка была действительной. (Также можно было бы переместить последнюю строку в try
блок, но имеет смысл ограничить содержимое этого блока только операторами, которые требуют специальной обработки ошибок.)
Ответ №2:
Когда вы определяете hp
внутри блока try-catch, его видимость находится внутри блока try. Следовательно, вы получаете ошибку компиляции в инструкции print вне блока try-catch .
Определите hp
перед началом блока try следующим образом:-
URL hp = null;
try{
hp = new URL("http://www.java2s.com");
System.out.println("it all worked?");
System.out.println(hp.getProtocol());
}catch (MalformedURLException e){
System.err.println("New URL failed");
System.err.println("exception thrown: " e.getMessage());
}
Чтобы лучше понять это, прочитайте раздел 14.4.2 Scope of Local Variable Declarations
здесь .
Также для более безопасной и правильной практики кодирования вы должны выбросить MalformedURLException
то, что вы перехватываете, с помощью предложения throw:-
catch (MalformedURLException e){
System.err.println("New URL failed");
System.err.println("exception thrown: " e.getMessage());
throw new MalformedURLException("Invalid URL!");
}
Вам также потребуется обновить свой main, чтобы создать это исключение:-
public static void main(String[] args) throws MalformedURLException
Если вы этого не сделаете, ваш код будет продолжен в случае неправильного URL-адреса!
Комментарии:
1. Небольшая проблема с вашим решением (первый блок кода) заключается в том, что при возникновении исключения MalformedURLException «hp» будет равно null, а окончательный оператор println вызовет исключение NullPointerException . (Вы ссылаетесь на это в своем комментарии «ваш код будет продолжен в случае неправильного URL-адреса»). Альтернативой было бы просто переместить этот println в блок try .
2. @Tim — ты прочитал полный код… Я добавил во второй раздел содержимое предложения throw (поэтому он никогда не будет использоваться в инструкции print, поскольку он выбрасывается). Конечно, оператор print может быть перемещен внутри блока try, но это выбор OP.