Я не могу подключить Socket к другому устройству - не могу оценить StructAddrinfo.toString () [duplicate]

Как я объясняю позже, я всегда предпочитаю методы TryParse и TryParseExact. Поскольку они немного громоздки для использования, я написал метод расширения, который упрощает разбор:

var    dtStr = "2011-03-21 13:26";
DateTime? dt = dtStr.toDate("yyyy-MM-dd HH:mm");

В отличие от Parse, ParseExact и т. Д. Он не генерирует исключение и позволяет вы проверите через

if (dt.HasValue) { // continue processing } else { // do error handling }

, было ли преобразование успешным (в этом случае dt имеет значение, к которому вы можете получить доступ через dt.Value) или нет (в этом случае , null).

Это даже позволяет использовать элегантные ярлыки, такие как «Elvis» -оператор ?., например:

int? year = dtStr?.toDate("yyyy-MM-dd HH:mm")?.Year;

Здесь вы также можете используйте year.HasValue, чтобы проверить, удалось ли преобразование, и если это не удалось, тогда year будет содержать null, в противном случае - годовую часть даты. Если преобразование не сработало, нет никакого исключения.

Попробуйте в .NetFiddle

public static class Extensions
{
    public static DateTime? toDate(this string dateTimeStr, string[] dateFmt)
    {
      // example: var dt = "2011-03-21 13:26".toDate(new string[]{"yyyy-MM-dd HH:mm", 
      //                                                  "M/d/yyyy h:mm:ss tt"});
      const DateTimeStyles style = DateTimeStyles.AllowWhiteSpaces;
      if (dateFmt == null)
      {
        var dateInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat;
        dateFmt=dateInfo.GetAllDateTimePatterns();
      }
      DateTime? result = null;
      DateTime dt;
      if (DateTime.TryParseExact(dateTimeStr, dateFmt,
         CultureInfo.InvariantCulture, style, out dt)) result = dt;
      return result;
    }

    public static DateTime? toDate(this string dateTimeStr, string dateFmt=null)
    {
      // example:   var dt="2011-03-21 13:26".toDate("yyyy-MM-dd HH:mm");
      // or simply  var dt="2011-03-21 13:26".toDate();        
      // call overloaded function with string array param
      string[] dateFmtArr = dateFmt == null ? null : new string[] { dateFmt };
      return toDate(dateTimeStr, dateFmtArr);
    }
}

Обновление: .toDate() (без параметров) теперь по умолчанию ко всем общим шаблонам даты / времени текущей культуры потока. Заметим, что нам нужны result и dt вместе, потому что TryParseExact не позволяет использовать DateTime?, который мы намерены вернуть. В C # Version 7 вы можете немного упростить функцию toDate следующим образом:

 // in C#7 only: "DateTime dt;" - no longer required, declare implicitly
 if (DateTime.TryParseExact(dateTimeStr, dateFmt,
     CultureInfo.InvariantCulture, style, out var dt)) result = dt;

(Также будет разрешено писать out DateTime dt вместо out var dt.)

Пример:

var dtStr="2011-03-21 13:26";    
var dt=dtStr.toDate("yyyy-MM-dd HH:mm");
if (dt.HasValue)
{
    Console.WriteLine("Successful!");
    // ... dt.Value now contains the converted DateTime ...
}
else
{
    Console.WriteLine("Invalid date format!");
}

Как вы можете видеть, этот пример просто запрашивает dt.HasValue, чтобы узнать, было ли преобразование успешным или нет. В качестве дополнительного бонуса TryParseExact позволяет указать строгую DateTimeStyles, чтобы вы точно знали, была ли передана правильная дата / время.


N.B. Перегруженная функция позволяет вам передать массив допустимых форматов, используемых для парсинга / преобразования дат, как показано здесь здесь (TryParseExact прямо поддерживает это), например

string[] dateFmt = {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", 
                     "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", 
                     "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", 
                     "M/d/yyyy h:mm", "M/d/yyyy h:mm", 
                     "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"};
var dtStr="5/1/2009 6:32 PM"; 
var dt=dtStr.toDate(dateFmt);

Однако, чтобы сохранить код коротким, я использую только перегрузку строкового массива TryParseExact, потому что он не работает с параметром Generic.

Расширенный пример: вы можете использовать оператор ?? по умолчанию к отказоустойчивому формату, например

var dtStr = "2017-12-30 11:37:00";
var dt = (dtStr.toDate()) ?? dtStr.toDate("yyyy-MM-dd HH:mm:ss");

. В этом случае .toDate() будет использовать общие форматы даты локальной культуры, и если все это не удастся, он попытается использовать ISO стандартный формат "yyyy-MM-dd HH:mm:ss" в качестве резервной копии. Таким образом, функция расширения позволяет легко «сгруппировать» различные резервные форматы.


Наконец, вот некоторые комментарии к фону (то есть причина, по которой я написал это так):

Я предпочитаю TryParseExact в этом методе расширения, потому что вы избегаете обработки исключений - вы можете прочитать статью Эрика Липперта об исключениях , почему вы должны использовать TryParse, а не Parse, я цитирую его об этом тема: 2)

Это неудачное дизайнерское решение1) [аннотация: чтобы метод Parse выкинул исключение] был настолько досадным, что, конечно, команда фреймворков внедрила TryParse вскоре после этого, что делает правильные вещи.

blockquote>

Это так, но TryParse и TryParseExact все еще намного меньше, чем удобно использовать: они заставляют вас использовать неинициализированную переменную в качестве параметра out, который не должен быть нулевым, и при преобразовании вам нужно оценить возвращаемое значение boolean - либо вы должны использовать if sta немедленно, или вам нужно сохранить возвращаемое значение в дополнительной логической переменной, чтобы вы могли выполнить проверку позже. И вы не можете просто использовать целевую переменную, не зная, было ли преобразование успешным или нет.

В большинстве случаев вам просто нужно знать , было ли преобразование успешным или нет (и, конечно, значение, если оно было успешным) , поэтому переменная с нулевым значением, которая сохраняет все информация была бы желательной и намного более изящной, поскольку вся информация просто хранится в одном месте: это непротиворечиво и простота в использовании и гораздо меньше подвержена ошибкам.

Метод расширения, который я написал, что (он также показывает вам, какой код вам придется писать каждый раз, если вы не собираетесь его использовать).

Я считаю, что преимущество .toDate(strDateFormat) в том, что он выглядит простым и чистым - так же просто, как предполагалось, оригинал DateTime.Parse, но с возможностью проверить, было ли преобразование успешным, и без исключений.


1) Что здесь имеется в виду это обработка исключений (т. е. блок try { ... } catch(Exception ex) { ...}), что необходимо, когда вы используете Parse, потому что он будет генерировать исключение, если синтаксический анализ недействительной строки - не только лишний y в этом случае, но также раздражает и усложняет ваш код. TryParse избегает всего этого, как показывает образец кода, который я предоставил.


2) Эрик Липперт - известный сотрудник StackOverflow и работает в Microsoft как основной разработчик в команде компилятора C # в течение нескольких лет.

210
задан Ziggy 26 May 2016 в 16:15
поделиться

12 ответов

Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int:

int x;
x = 10;

В этом примере переменная x является int, и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.

Но когда вы пытаетесь объявить ссылочный тип, произойдет что-то другое. Возьмите следующий код:

Integer num;
num = new Integer(10);

Первая строка объявляет переменную с именем num, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

Во второй строке ключевое слово new используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования . (точка).

Exception, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num. Перед созданием объекта вы получите NullPointerException. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

public void doSomething(SomeObject obj) {
   //do something to obj
}

В этом случае вы не создаете объект obj, скорее предполагая, что он был создан до вызова метода doSomething. К сожалению, этот метод можно вызвать следующим образом:

doSomething(null);

В этом случае obj имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException, потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.

Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething может быть записано как:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj != null) {
       //do something
    } else {
       //do something else
    }
}

Наконец, Как определить исключение & amp; причина использования Трассировки стека

3220
ответ дан 16 revs, 14 users 63% 25 August 2018 в 01:49
поделиться
438
ответ дан 10 revs, 6 users 87% 25 August 2018 в 01:49
поделиться

Другое событие 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));
}
247
ответ дан 2 revs, 2 users 97% 25 August 2018 в 01:49
поделиться

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

293
ответ дан 4 revs, 4 users 57% 25 August 2018 в 01:49
поделиться

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

257
ответ дан 4 revs, 4 users 79% 25 August 2018 в 01:49
поделиться

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

315
ответ дан 5 revs, 4 users 55% 25 August 2018 в 01:49
поделиться

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

Например, ниже - класс ученика, который будет использовать его в нашем коде.

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
277
ответ дан 5 revs, 4 users 61% 25 August 2018 в 01:49
поделиться

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).
280
ответ дан 5 revs, 4 users 68% 25 August 2018 в 01:49
поделиться

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
366
ответ дан 5 revs, 5 users 38% 25 August 2018 в 01:49
поделиться

В Java все находится в форме класса.

Если вы хотите использовать любой объект, тогда у вас есть две фазы:

  1. Объявить
  2. Инициализация

Пример:

  • Объявление: Object a;
  • Инициализация: a=new Object();

То же самое для концепции массива

  • Объявление: Item i[]=new Item[5];
  • Инициализация: i[0]=new Item();

Если вы не дают секцию инициализации, тогда возникает NullpointerException.

269
ответ дан 5 revs, 5 users 58% 25 August 2018 в 01:49
поделиться

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно 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 = "";

Либо метод print, либо 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 ).

612
ответ дан 7 revs, 5 users 89% 25 August 2018 в 01:49
поделиться

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

758
ответ дан 8 revs, 5 users 74% 25 August 2018 в 01:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: