Char и разность между массивами int
Когда я пытаюсь напечатать неинициализированный массив static char, он дает ошибку времени выполнения (исключение Null pointer), тогда как неинициализированный массив static int дает значение null. Почему?
public class abc {
static int arr[];
static char ch[];
public static void main(String[] args) {
System.out.println(ch); //it gives null pointer exception at run time
System.out.println(arr); //it gives output as "null".
}
}
Ответы
Ответ 1
System.out
- это экземпляр PrintStream
, и этот класс имеет несколько перегруженных методов println
. В вашем случае:
-
System.out.println(ch);
использует public void println(char x[])
-
System.out.println(arr);
использует public void println(Object x)
(нет метода public void println(int[] x)
, поэтому ближайший доступный тип для int[]
, который может использовать println
, - Object
).
Второй метод использует
String.valueOf(x);
чтобы получить строковое представление объекта, который мы хотим распечатать, и код метода valueOf
выглядит как
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
чтобы он был нулевым (вернет строку "null"
, если ссылка содержит null
).
Первый метод находится на некотором уровне, используя
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
// ^^^^^^^ this throws NPE
}
и потому что cbuf
есть null
cbuf.length
будет вызывать исключение NullPointerException, потому что null
не имеет поля length
(или любого другого).
Ответ 2
Ответ существует в исходном коде PrintWriter
(из которого System.out
является экземпляром).
Начните с того, что неинициализированные массивы в качестве ссылочных переменных заданы по умолчанию null
.
println(char[])
(в конечном итоге) пытается вызвать .length
в переданном массиве. Он равен нулю, в результате получится NullPointerException
. println(char[])
(в конечном итоге) вызывает write(char[])
:
public void write(char buf[]) {
write(buf, 0, buf.length);
}
Нет перегрузки println
соответствия int[]
, но существует println(Object)
. Там он (в конце концов) пытается String.valueOf
, передавая ссылку null
, поэтому String.valueOf
принимает null
и возвращает String
"null"
. println(Object)
вызывает print(Object)
:
public void print(Object obj) {
write(String.valueOf(obj));
}
Ответ 3
Это два разных метода, и их API полностью описывают поведение.
public void println(Object x)
сначала вызывает String.valueOf, который возвращает "null", если x равно null.
См:
public void print(char[] c)
вызывает метод print (char [] c), который выдает исключение NullPointerException, если c имеет значение null.
См:
Ответ 4
Фактически вы вызываете два разных перегруженных метода System.out.println()
. public void println(char[] x)
перегружен согласно документации. Конкретная перегрузка println(Object x)
не существует для массивов int[]
.
Итак, когда println()
вызывается в целочисленном массиве, вызывается public void println(Object x)
. Согласно Javadocs:
Этот метод вызывает сначала String.valueOf(x), чтобы получить распечатанную object string value, а затем ведет себя так, как будто он вызывает печать (String) а затем println().
Так как значение строки null
, метод печатает null.
Метод println()
работает несколько иначе, когда в качестве параметра принимает массив символов. Поверхностно, сам метод кажется похожим:
Печатает массив символов, а затем завершает линию. Этот метод ведет себя так, как будто он вызывает печать (char []), а затем println().
Однако метод print(char[])
ведет себя по-разному ключевыми способами:
Печатает массив символов. Символы преобразуются в байты в соответствии с кодировкой символов по умолчанию платформы, и эти байты записываются точно так же, как метод write (int).
Таким образом, он вызывает другой метод. В документации для print(char[])
явно указано, что в вашей ситуации вы выбрали исключение:
Throws: NullPointerException - если [входной параметр] s имеет значение null
Следовательно, причина различия в поведении.
Подробнее о методах println
и print
см. Javadocs:
http://docs.oracle.com/javase/7/docs/api/java/io/PrintStream.html#println()