Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа 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; причина использования Трассировки стека
Я наткнулся на Ваш вопрос, ища ту же точную вещь. Я закончил тем, что использовал Отражатель , чтобы выяснить, как ASP.NET Button
управление на самом деле представляется. Оказывается действительно легким измениться.
Это действительно просто сводится к переопределению TagName
и TagKey
свойства Button
класс. После выполнения этого просто необходимо удостовериться, что Вы представляете содержание кнопки вручную, так как исходный Button
класс никогда не имел содержание для рендеринга, и управление представит текстовую меньше кнопку, если Вы не представите содержание.
Обновление:
возможно сделать несколько маленьких модификаций к Кнопочному управлению посредством наследования и все еще работать довольно хорошо. Это решение избавляет от необходимости реализовывать Ваши собственные обработчики событий для OnCommand (хотя, если Вы хотите изучить, как сделать это, я могу показать Вам, как это обрабатывается). Это также устраняет проблему представления значения, которое имеет разметку в нем, за исключением IE, вероятно. Я все еще не уверен, как зафиксировать плохую реализацию IE тега Кнопки все же. Это может просто быть действительно техническим ограничением, которое невозможно работать вокруг...
[ParseChildren(false)]
[PersistChildren(true)]
public class ModernButton : Button
{
protected override string TagName
{
get { return "button"; }
}
protected override HtmlTextWriterTag TagKey
{
get { return HtmlTextWriterTag.Button; }
}
// Create a new implementation of the Text property which
// will be ignored by the parent class, giving us the freedom
// to use this property as we please.
public new string Text
{
get { return ViewState["NewText"] as string; }
set { ViewState["NewText"] = HttpUtility.HtmlDecode(value); }
}
protected override void OnPreRender(System.EventArgs e)
{
base.OnPreRender(e);
// I wasn't sure what the best way to handle 'Text' would
// be. Text is treated as another control which gets added
// to the end of the button's control collection in this
//implementation
LiteralControl lc = new LiteralControl(this.Text);
Controls.Add(lc);
// Add a value for base.Text for the parent class
// If the following line is omitted, the 'value'
// attribute will be blank upon rendering
base.Text = UniqueID;
}
protected override void RenderContents(HtmlTextWriter writer)
{
RenderChildren(writer);
}
}
Для использования этого управления у Вас есть несколько опций. Нужно поместить средства управления непосредственно в разметку ASP.
<uc:ModernButton runat="server"
ID="btnLogin"
OnClick="btnLogin_Click"
Text="Purplemonkeydishwasher">
<img src="../someUrl/img.gif" alt="img" />
<asp:Label ID="Label1" runat="server" Text="Login" />
</uc:ModernButton>
можно также добавить средства управления к набору управления кнопки в коде - позади.
// This code probably won't work too well "as is"
// since there is nothing being defined about these
// controls, but you get the idea.
btnLogin.Controls.Add(new Label());
btnLogin.Controls.Add(new Table());
я не знаю, как хорошо комбинация обеих опций работает, поскольку я не протестировал это.
единственный недостаток к этому управлению прямо сейчас - то, что я не думаю, что оно будет помнить Ваши средства управления через PostBacks. Я не протестировал это так, это может уже работать, но я сомневаюсь, что это делает. Необходимо будет добавить некоторый код управления состоянием отображения, чтобы подсредства управления были обработаны через PostBacks, я думаю, однако это, вероятно, не проблема для Вас. Добавление поддержки ViewState не должно быть ужасно трудно сделать, хотя в случае необходимости, который может легко быть добавлен.
Вы могли сделать новое управление, наследовавшееся Кнопке, и переопределить метод рендеринга или использовать .browser файл для переопределения всех Кнопок в сайте, подобном пути CSS, которым Дружественные работы материала для TreeView управляют и т.д.
Можно использовать Кнопка. Свойство UseSubmitBehavior, как обсуждено в эта статья о рендеринге Кнопочного управления ASP.NET как кнопка .
<час> РЕДАКТИРОВАНИЕ: Извините.. это - то, что я получаю для просматривания вопросов в мой обеденный перерыв. Есть ли причины, почему Вы просто не использовали бы < кнопка runat = "сервер" > тег или HtmlButton?Я пошел бы с LinkButton и разработал бы его с CSS как соответствующий.
Я весь день боролся с этим - мой собственный
сгенерированный элемент управления не работает:
System.Web.HttpRequestValidationException: от клиента обнаружено потенциально опасное значение Request.Form
Что происходит, так это то, что .Net добавляет атрибут name
:
<button type="submit" name="ctl02" value="Content" class="btn ">
<span>Content</span>
</button>
Атрибут name
выдает ошибку сервера при использовании IE 6 и IE 7. Все отлично работает в других браузерах (Opera, IE 8, Firefox, Safari).
Лекарство - взломать этот атрибут name
. Я до сих пор этого не понял.
Хотя вы говорите, что с помощью [button runat = "server" ] не является достаточно хорошим решением, важно упомянуть об этом - многие программисты .NET боятся использовать «родные» HTML-теги ...
Использование:
<button id="btnSubmit" runat="server" class="myButton"
onserverclick="btnSubmit_Click">Hello</button>
Обычно это работает отлично, и все довольны в моей команде.