Хорошим местом для начала является JavaDocs . Они охватывают это:
Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:
- Вызов метода экземпляра нулевого объекта.
- Доступ или изменение поля нулевого объекта.
- Выполнение длины null, как если бы это был массив.
- Доступ или изменение слотов с нулевым значением, как если бы это был массив.
- Бросать нуль, как если бы это было значение Throwable.
Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.
blockquote>Также, если вы попытаетесь использовать нулевую ссылку с
synchronized
, который также выдаст это исключение, за JLS :SynchronizedStatement: synchronized ( Expression ) Block
blockquote>
- В противном случае, если значение выражения равно null,
NullPointerException
.Как это исправить?
Итак, у вас есть
NullPointerException
. Как вы это исправите? Возьмем простой пример, который выдаетNullPointerException
:public class Printer { private String name; public void setName(String name) { this.name = name; } public void print() { printString(name); } private void printString(String s) { System.out.println(s + " (" + s.length() + ")"); } public static void main(String[] args) { Printer printer = new Printer(); printer.print(); } }
Идентифицирует нулевые значения
. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:
Exception in thread "main" java.lang.NullPointerException at Printer.printString(Printer.java:13) at Printer.print(Printer.java:9) at Printer.main(Printer.java:19)
Здесь мы видим, что исключение выбрано в строке 13 (в методе
printString
). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, чтоs
имеет значение null, а вызов методаlength
на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когдаs.length()
удаляется из метода.Трассировка, где эти значения взяты из
Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что
s
передается сprintString(name)
в методеprint()
, аthis.name
- null.Трассировка, где эти значения должны быть установлены
Где установлен
this.name
? В методеsetName(String)
. С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. Этого достаточно, чтобы дать нам решение: добавить вызов
printer.setName()
перед вызовомprinter.print()
.Другие исправления
Переменная может иметь значение по умолчанию (и
setName
может помешать ему установить значение null):private String name = "";
Либо метод
printString
может проверить значение null например:printString((name == null) ? "" : name);
Или вы можете создать класс, чтобы
name
всегда имел ненулевое значение :public class Printer { private final String name; public Printer(String name) { this.name = Objects.requireNonNull(name); } public void print() { printString(name); } private void printString(String s) { System.out.println(s + " (" + s.length() + ")"); } public static void main(String[] args) { Printer printer = new Printer("123"); printer.print(); } }
См. также:
Я все еще не могу найти проблему
Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).
Чтобы поддерживать повторное использование и возможность обернуть это в объект / функцию, давайте его параметризуем:
var str = "abcdefoihewfojias".split('');
var nth = 4; // the nth character you want to replace
var replaceWith = "|" // the character you want to replace the nth value
for (var i = nth-1; i < str.length-1; i+=nth) {
str[i] = replaceWith;
}
alert( str.join("") );
Хотя уже есть несколько ответов, я подумал, что предлагаю немного альтернативный подход, используя Array.prototype.map()
, завернутый в функцию, которая может быть адаптирована пользователем (для обновления значения n
в символе nth
и измените используемый символ замены):
// defining the named function, with an 'opts' argument:
function replaceNthWith(opts) {
// setting the default options:
var defaults = {
// defining the nth character, in this case
// every fourth:
'nth': 4,
// defining the character to replace that
// nth character with:
'char': '|'
};
// Note that there's no default string argument,
// so that one argument must be provided in the
// opts object.
// iterating over each property in the
// opts Object:
for (var property in opts) {
// if the current property is a property of
// this Object, not inherited from the Object
// prototype:
if (opts.hasOwnProperty(property)) {
// we set that property of the defaults
// Object to be equal to that property
// as set in the opts Object:
defaults[property] = opts[property];
}
}
// if there is a defaults.string property
// (inherited from the opts.string property)
// then we go ahead; otherwise nothing happens
// note: this property must be set for the
// function to do anything useful:
if (defaults.string) {
// here we split the string supplied from the user,
// via opts.string, in defaults.string to form an
// Array of characters; we iterate over that Array
// with Array.prototype.map(), which process one
// Array and returns a new Array according to the
// anonymous function supplied:
return haystack = defaults.string.split('').map(function(character, index) {
// here, when the index of the current letter in the
// Array formed by Array.prototype.split() plus 1
// (JavaScript is zero-based) divided by the number
// held in defaults.nth is equal to zero - ensuring
// that the current letter is the 'nth' index we return
// the defaults.char character; otherwise we return
// the original character from the Array over which
// we're iterating:
return (index + 1) % parseInt(defaults.nth) === 0 ? defaults.char : character;
// here we join the Array back into a String, using
// Array.prototype.join() with an empty string:
}).join('');
}
}
// 'snippet.log()' is used only in this demonstration, in real life use
// 'console.log()', or print to screen or display in whatever other
// method you prefer:
snippet.log( replaceNthWith({ 'string': "abcdefoihewfojias" }) );
function replaceNthWith(opts) {
var defaults = {
'nth': 4,
'char': '|'
};
for (var property in opts) {
if (opts.hasOwnProperty(property)) {
defaults[property] = opts[property];
}
}
if (defaults.string) {
return haystack = defaults.string.split('').map(function(character, index) {
return (index + 1) % parseInt(defaults.nth) === 0 ? defaults.char : character;
}).join('');
}
}
// 'snippet.log()' is used only in this demonstration, in real life use
// 'console.log()', or print to screen or display in whatever other
// method you prefer.
// calling the function, passing in the supplied 'string'
// property value:
snippet.log( replaceNthWith({
'string': "abcdefoihewfojias"
}) );
// outputs: abc|efo|hew|oji|s
// calling the function with the same string, but to replace
// every second character ( 'nth' : 2 ):
snippet.log( replaceNthWith({
'string': "abcdefoihewfojias",
'nth': 2
}) );
// outputs: a|c|e|o|h|w|o|i|s
// passing in the same string once again, working on every
// third character, and replacing with a caret ('^'):
snippet.log( replaceNthWith({
'string': "abcdefoihewfojias",
'nth': 3,
'char' : '^'
}) );
// outputs: ab^de^oi^ew^oj^as
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Ссылки:
Вы можете использовать этот однострочный:
var str = "abcdefoihewfojias";
str.split('').map(function(l,i) {
return (i + 1) % 4 ? l : '|';
}).join('');
%
возвращает остаток. Итак:
# | Result (# + 1) % 4
---|-------
0 | 1
1 | 2
2 | 3
4 | 0 // Bingo!
С ES6 вы можете сделать:
[...str].map((l,i) => (i + 1) % 4 ? l : '|')
Вы могли бы просто сделать это с заменой регулярного выражения:
var str = "abcdefoihewfojias";
var result = str.replace(/(...)./g, "$1|");
console.log(result);
Простой пример использования модуля
https://jsfiddle.net/ctfsorwg/
var str = "abcdefoihewfojias";
var outputStr = str.split("");
for (var i = 0; i < outputStr.length; i++) {
if(!((i+1)%4))outputStr[i] = '|';
}
alert( "Before: " + str + "\nAfter: " + outputStr.join(""));
charAt
– Downgoat 16 August 2015 в 01:15