Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа 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; причина использования Трассировки стека
Причина using
оператор должен гарантировать, что объект расположен, как только это выходит из объема, и это не требует, чтобы явный код гарантировал, что это происходит.
Как в Понимание оператора 'использования' в C#, CLR.NET преобразовывает
using (MyResource myRes = new MyResource())
{
myRes.DoSomething();
}
к
{ // Limits scope of myRes
MyResource myRes= new MyResource();
try
{
myRes.DoSomething();
}
finally
{
// Check for a null resource.
if (myRes != null)
// Call the object's Dispose method.
((IDisposable)myRes).Dispose();
}
}
Синтаксис Записи-считывания Насмешек Носорога делает интересное использование using
.
Все вне фигурных скобок расположено, таким образом, замечательно расположить Ваши объекты, если Вы не используете их. Это так, потому что, если Вы сделали, чтобы SqlDataAdapter возразил и Вы используете его только однажды в жизненном цикле приложения, и Вы заполняете всего один набор данных, и Вам больше не нужен он, можно использовать код:
using(SqlDataAdapter adapter_object = new SqlDataAdapter(sql_command_parameter))
{
// do stuff
} // here adapter_object is disposed automatically
Другой пример разумного использования, в котором сразу расположен объект:
using (IDataReader myReader = DataFunctions.ExecuteReader(CommandType.Text, sql.ToString(), dp.Parameters, myConnectionString))
{
while (myReader.Read())
{
MyObject theObject = new MyObject();
theObject.PublicProperty = myReader.GetString(0);
myCollection.Add(theObject);
}
}
Не то, чтобы это крайнее важный, но использование может также использоваться для изменения ресурсов на лету. Да доступный, как отмечалось ранее, но возможно конкретно Вы не хотите ресурсы, которым они не соответствуют с другими ресурсами во время остальной части Вашей казни. Таким образом, Вы хотите избавиться от него так, это не вмешивается в другом месте.
Благодаря комментариям ниже, я очищу это сообщение немного (я не должен был использовать слова 'сборка "мусора"' в то время, извинения):
при использовании использования оно назовет Расположение () метод на объекте в конце объема использования. Таким образом, у Вас может быть довольно мало большого кода очистки в Вашем Располагающий () метод.
пункт маркированного списка А здесь, который, надо надеяться, возможно, получит этот un-markeddown: при реализации IDisposable удостоверьтесь, что Вы называете GC.SuppressFinalize () в Вашем Располагать () реализацию, поскольку в других отношениях автоматическая сборка "мусора" попытается прийти и Завершить его в какой-то момент, который самое меньшее был бы тратой ресурсов, если Вы имеете, уже Располагают () d его.
использование используется, когда у Вас есть ресурс, который Вы хотите расположенный после того, как оно использовалось.
, Например, если Вы выделяете ресурс Файла и только должны использовать его в одном разделе кода для небольшого чтения или записи, использование полезно для избавления от ресурса Файла как только Ваш сделанный.
ресурс, используемый потребности реализовать IDisposable для работы правильно.
Пример:
using (File file = new File (parameters))
{
*code to do stuff with the file*
}
Ключевое слово использования определяет объем для объекта и затем избавляется от объекта, когда объем завершен. Например.
using (Font font2 = new Font("Arial", 10.0f))
{
// use font2
}
См. здесь для статьи MSDN о C# с помощью ключевого слова.
"использование" может также использоваться для разрешения конфликтов пространства имен. См. http://www.davidarno.org/c-howtos/aliases-overcoming-name-conflicts/ для короткого учебного руководства, которое я записал на предмете.
При использовании ADO.NET можно использовать keywork для вещей как объект соединения или объект читателя. Тот путь, когда блок кода завершит его, автоматически избавится от Вашего соединения.
В заключение когда Вы используете локальную переменную типа, который реализует IDisposable
, всегда , без исключения, используйте using
<глоток> 1 глоток>.
, Если Вы используете нелокальный IDisposable
, переменные, тогда всегда реализуют IDisposable
шаблон .
Два простых правила, никакое исключение <глоток> 1 глоток>. Предотвращение утечек ресурсов иначе является реальной болью в *ss.
<час> <глоток> 1) глоток>: единственным исключением является †“В, когда Вы обрабатываете исключения. Это могло бы тогда быть меньше кода для вызова Dispose
явно в finally
блок.
Интересно, можно также использовать using/IDisposable шаблон для других интересных вещей (таких как другая точка пути, который Насмешки Носорога использует его). В основном можно использовать в своих интересах то, что компилятор будет всегда вызов.Dispose на "используемом" объекте. Если у Вас есть что-то, что должно произойти после определенной операции... что-то, что имеет определенный запуск и конец... тогда, можно просто сделать класс IDisposable, который запускает операцию в конструкторе, и затем заканчивается в Расположить методе.
Это позволяет Вам использовать действительно хороший синтаксис использования для обозначения явного запуска и конца упомянутой операции. Это также как Система. Транзакции наполняют работы.
Другое большое использование использования при инстанцировании модального диалогового окна.
Using frm as new Form1
Form1.ShowDialog
' do stuff here
End Using
Я использовал его много в прошлом для работы с входными и выходными потоками. Можно вложить их приятно, и это устраняет много потенциальных проблем, с которыми Вы обычно сталкиваетесь (автоматическим вызовом, располагают). Например:
using (FileStream fs = new FileStream("c:\file.txt", FileMode.Open))
{
using (BufferedStream bs = new BufferedStream(fs))
{
using (System.IO.StreamReader sr = new StreamReader(bs))
{
string output = sr.ReadToEnd();
}
}
}
использование может использоваться для вызова IDisposable. Это может также использоваться для искажения типов.
using (SqlConnection cnn = new SqlConnection()) { /*code*/}
using f1 = System.Windows.Forms.Form;
использование, в смысле
using (var foo = new Bar())
{
Baz();
}
Является на самом деле стенографией для блока попытки/наконец. Это эквивалентно коду:
var foo = new Bar();
try
{
Baz();
}
finally
{
foo.Dispose();
}
Вы отметите, конечно, что первый отрывок намного более краток, чем второе и также что существует много видов вещей, которые Вы могли бы хотеть сделать как очистка, даже если исключение выдается. Из-за этого мы придумали класс, что мы называем Объем, который позволяет Вам выполнять произвольный код в Расположить методе. Так, например, если бы у Вас было свойство под названием IsWorking, который Вы всегда хотели установить на ложь после попытки выполнить операцию, Вы сделали бы это как это:
using (new Scope(() => IsWorking = false))
{
IsWorking = true;
MundaneYetDangerousWork();
}
можно читать больше о нашем решении и как мы получили его здесь .
Вещи как это:
using (var conn = new SqlConnection("connection string"))
{
conn.Open();
// Execute SQL statement here on the connection you created
}
Это SqlConnection
будет закрыто, не будучи должен явно звонить эти .Close()
функция, и это произойдет , даже если исключение будет выдано без потребности в try
/ catch
/ finally
.
Так как много людей все еще делает:
using (System.IO.StreamReader r = new System.IO.StreamReader(""))
using (System.IO.StreamReader r2 = new System.IO.StreamReader("")) {
//code
}
я предполагаю, что много людей все еще не знает, что можно сделать:
using (System.IO.StreamReader r = new System.IO.StreamReader(""), r2 = new System.IO.StreamReader("")) {
//code
}