Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Другие ответы хороши, но вот еще одна опция. Это позволяет Вам сохранять ту же форму, с которой Вы запустили, но используете прием именования Вашей функции лямбды так, чтобы можно было обратиться к нему рекурсивно:
mapstrings = ['mapstring1', 'mapstring2', 'mapstring3'];
geocoder.getLatLng(mapstrings.shift(), function lambda(point) {
if(point) {
// success
map.setCenter(point, 13);
map.setZoom(7);
map.addOverlay(new GMarker(point));
}
else if(mapstrings.length > 0) {
// Previous mapstring failed... try next mapstring
geocoder.getLatLng(mapstrings.shift(), lambda);
}
else {
// Take special action if no mapstring succeeds?
}
})
В первый раз, когда символ "лямбда" используется, это должно представить его как новое функциональное литеральное имя. Во второй раз, когда это используется, это - рекурсивная ссылка.
функциональное литеральное именование работает в Chrome, и я предполагаю, что это работает в большинстве современных браузеров, но я не протестировал его, и я не знаю о более старых браузерах.
Как насчет этого?
function place_point(mapstrings,idx)
{
if(idx>=mapstrings.length) return;
geocoder.getLatLng(mapstrings[idx],
function(point)
{
if(!point)
{
place_point(mapstrings,idx+1);
return;
}
map.setCenter(point, 13);
map.setZoom(7);
map.addOverlay(new GMarker(point));
});
}
столько резервного копирования представляет в виде строки, сколько Вы хотите. Просто назовите его с 0 как второй аргумент в первый раз.
Да, факторизуйте его в функцию :)
geocoder.getLatLng(item.mapstring, function(point) {
if (!point) {
geocoder.getLatLng(item.backup_mapstring, function(point) {
if (point) {
setPoint(point);
}
})
return;
}
function setPoint(point) {
map.setCenter(point, 13);
map.setZoom(7);
map.addOverlay(new GMarker(point));
}
setPoint(point);
});
Существует чрезвычайно хороший метод для выполнения рекурсии в конструкциях языка, которые явно не поддерживают рекурсию, названную комбинатор неподвижной точки . Самое известное Y-Combinator.
Вот Y combinator для функции одного параметра в Javascript:
function Y(le, a) {
return function (f) {
return f(f);
}(function (f) {
return le(function (x) {
return f(f)(x);
}, a);
});
}
Это выглядит немного страшным, но только необходимо записать что однажды. Используя его на самом деле довольно просто. В основном Вы берете свою исходную лямбду одного параметра, и Вы превращаете его в новую функцию двух параметров - первый параметр является теперь фактическим лямбда-выражением, на котором можно сделать рекурсивный вызов, второй параметр является исходным первым параметром (point
), что Вы хотите использовать.
Это - то, как Вы могли бы использовать его в своем примере. Обратите внимание, что я использую mapstrings
в качестве списка строк для поиска, и поп-функция пагубно удалила бы элемент от главы.
geocoder.getLatLng(pop(mapstrings), Y(
function(getLatLongCallback, point)
{
if (!point)
{
if (length(mapstrings) > 0)
geocoder.getLatLng(pop(mapstrings), getLatLongCallback);
return;
}
map.setCenter(point, 13);
map.setZoom(7);
map.addOverlay(new GMarker(point));
});