Добавление случая, когда имя класса для объекта, используемого в структуре сущности, такое же, как имя класса для файла с кодировкой веб-формы.
Предположим, у вас есть веб-форма Contact.aspx, чей класс codebehind Свяжитесь с вами, и у вас есть имя объекта Contact.
Затем следующий код вызовет исключение NullReferenceException при вызове context.SaveChanges ()
Contact contact = new Contact { Name = "Abhinav"};
var context = new DataContext();
context.Contacts.Add(contact);
context.SaveChanges(); // NullReferenceException at this line
Ради полноты класса DataContext
public class DataContext : DbContext
{
public DbSet Contacts {get; set;}
}
и класс сущности контакта. Иногда классы сущностей являются частичными классами, так что вы можете распространять их и в других файлах.
public partial class Contact
{
public string Name {get; set;}
}
Ошибка возникает, когда оба класса entity и codebehind находятся в одном и том же пространстве имен. Чтобы исправить это, переименуйте класс сущности или класс codebehind для Contact.aspx.
Причина. Я все еще не уверен в причине. Но всякий раз, когда какой-либо из классов сущностей расширяет System.Web.UI.Page, возникает эта ошибка.
Для обсуждения рассмотрим NullReferenceException в DbContext.saveChanges ()
Единственная необходимость использовать квалификатор this.
- это когда другая переменная в текущей области имеет одно имя и вы хотите обратиться к члену экземпляра (как описывает Уильям). Кроме того, нет разницы в поведении между x
и this.x
.
Что касается сообщений Уильяма Бренделя и dbconfessions , в отношении случая 2. Вот пример:
public class Window {
private Window parent;
public Window (Window parent) {
this.parent = parent;
}
public void addSubWindow() {
Window child = new Window(this);
list.add(child);
}
public void printInfo() {
if (parent == null) {
System.out.println("root");
} else {
System.out.println("child");
}
}
}
I ' Видно, что это использовалось при построении отношений родитель-ребенок с объектами. Однако, пожалуйста, учтите, что для краткости это упрощено.
Будет ли какая-либо разница, если я использую «x» вместо «this.x» в некоторых методах?
Обычно нет. Но иногда это имеет значение:
class A {
private int i;
public A(int i) {
this.i = i; // this.i can be used to disambiguate the i being referred to
}
}
Если я просто использую метод (), не будет ли он по умолчанию применяться к текущему объекту?
Да. Но при необходимости this.method()
разъясняет, что вызов выполняется этим объектом.
this
полезен в шаблоне построителя.
public class User {
private String firstName;
private String surname;
public User(Builder builder){
firstName = builder.firstName;
surname = builder.surname;
}
public String getFirstName(){
return firstName;
}
public String getSurname(){
return surname;
}
public static class Builder {
private String firstName;
private String surname;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setSurname(String surname) {
this.surname = surname;
return this;
}
public User build(){
return new User(this);
}
}
public static void main(String[] args) {
User.Builder builder = new User.Builder();
User user = builder.setFirstName("John").setSurname("Doe").build();
}
}
«this» также полезно при вызове одного конструктора из другого:
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
Google поднял страницу на сайте Sun, которая немного обсуждает это.
Вы правы в переменной; this
действительно может использоваться для дифференциации переменной метода из поля класса. [f1]
Однако, я действительно ненавижу это соглашение. Предоставление двух разных переменных буквально одинаковых имен - это рецепт ошибок. Я предпочитаю что-то вроде: [f2]
Те же результаты, но без шансов на ошибку, когда вы случайно ссылаетесь на x
, когда вы действительно хотели ссылаться на x
.
Что касается использования этого метода, вы правы в отношении эффектов; вы получите те же результаты с или без него. Вы можете использовать его? Конечно. Должны ли вы использовать его? До вас, но, учитывая, что я лично считаю бессмысленной многословность, которая не добавляет ясности (если код не заполнен статическими операторами импорта), я не склонен использовать его сам.
Если у вас нет совпадающих имен переменных, это действительно просто для ясности, когда вы читаете код.
Второе важное использование this
(помимо скрытия с локальной переменной, о чем уже говорят многие ответы) - это обращение к внешнему экземпляру из вложенного нестатического класса:
public class Outer {
protected int a;
public class Inner {
protected int a;
public int foo(){
return Outer.this.a;
}
public Outer getOuter(){
return Outer.this;
}
}
}
this
не влияет на итоговый код - это оператор времени компиляции, и код, сгенерированный с ним или без него, будет таким же. Когда вы должны использовать его, зависит от контекста. Например, вы должны использовать его, как вы сказали, когда у вас есть локальная переменная, которая изменяет переменную класса, и вы хотите ссылаться на переменную класса, а не на локальную.
изменить: по «результирующий код будет тот же «Я имею в виду, конечно, когда какая-то переменная в локальной области не скрывает того, что принадлежит классу. Таким образом,
class POJO {
protected int i;
public void modify() {
i = 9;
}
public void thisModify() {
this.i = 9;
}
}
полученный код обоих методов будет таким же. Разница будет в том, что если какой-либо метод объявляет локальную переменную с тем же именем
public void m() {
int i;
i = 9; // i refers to variable in method's scope
this.i = 9; // i refers to class variable
}
Вам нужно использовать this
- и большинство людей используют его только при наличии локальной локальной переменной с таким же именем. (Например, методы сеттера.)
Конечно, еще одна веская причина использовать this
в том, что она вызывает всплытие intellisense в IDE:)
, когда есть две переменные, одна переменная экземпляра и другая локальная переменная с тем же именем, мы используем это. для ссылки на текущий исполняемый объект, чтобы избежать конфликта между именами.
Есть много хороших ответов, но есть еще одна очень небольшая причина, чтобы поместить this
всюду. Если вы попытались открыть исходные коды из обычного текстового редактора (например, блокнот и т. Д.), Использование this
сделает его более понятным для чтения.
Представьте это:
public class Hello {
private String foo;
// Some 10k lines of codes
private String getStringFromSomewhere() {
// ....
}
// More codes
public class World {
private String bar;
// Another 10k lines of codes
public void doSomething() {
// More codes
foo = "FOO";
// More codes
String s = getStringFromSomewhere();
// More codes
bar = s;
}
}
}
Это очень понятно для чтения с любой современной IDE, но это будет полный кошмар для чтения с помощью обычного текстового редактора.
Вам будет трудно узнать, где находится foo
, пока вы не используйте функцию «Найти» редактора. Тогда вы будете кричать на getStringFromSomewhere()
по той же причине. Наконец, после того, как вы забыли, что s
есть, bar = s
даст вам последний удар.
Сравните это с этим:
public void doSomething() {
// More codes
Hello.this.foo = "FOO";
// More codes
String s = Hello.this.getStringFromSomewhere();
// More codes
this.bar = s;
}
foo
- переменная, объявленная во внешнем классе Hello
. getStringFromSomewhere()
- это метод, объявленный также в внешнем классе. bar
принадлежит классу World
, а s
- локальная переменная, объявленная в этом методе. Конечно, всякий раз, когда вы что-то создаете, вы создаете правила. Поэтому при разработке вашего API или проекта, если ваши правила включают «если кто-то открывает все эти исходники с помощью блокнота, он или она должен стрелять в себя в голову», тогда вы совершенно не хотите делать это .
Ключевое слово this
используется в основном в трех ситуациях. Первый и наиболее распространенный в методах setter для устранения неоднозначности ссылок на переменные. Во-вторых, когда необходимо передать текущий экземпляр класса в качестве аргумента методу другого объекта. Третий - это способ вызова альтернативных конструкторов из конструктора.
Случай 1: Использование this
для устранения неоднозначности ссылок на переменные. В методах настройки Java мы обычно передаем аргумент с тем же именем, что и переменная частного члена, которую мы пытаемся установить. Затем мы назначим аргумент x
на this.x
. Это дает понять, что вы присваиваете значение параметра «name» переменной экземпляра «name».
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
Случай 2: Использование this
в качестве аргумента, переданного другому объекту.
public class Foo
{
public String useBarMethod() {
Bar theBar = new Bar();
return theBar.barMethod(this);
}
public String getName() {
return "Foo";
}
}
public class Bar
{
public void barMethod(Foo obj) {
obj.getName();
}
}
Случай 3: Использование this
для вызова альтернативных конструкторов. В комментариях trinithis правильно указал еще одно общее использование this
. Когда у вас есть несколько конструкторов для одного класса, вы можете использовать this(arg0, arg1, ...)
для вызова другого конструктора по вашему выбору, если вы делаете это в первой строке своего конструктора.
class Foo
{
public Foo() {
this("Some default value for bar");
//optional other lines
}
public Foo(String bar) {
// Do something with bar
}
}
Я также видел this
используется для того, чтобы подчеркнуть тот факт, что на переменную экземпляра ссылаются (без необходимости устранения неоднозначности), но это редкий случай, на мой взгляд.
Чтобы убедиться, что используются элементы текущего объекта. Случаи, связанные с безопасностью потоков, некоторые приложения могут изменять неправильные значения элементов объектов, поэтому это должно быть применено к элементу, чтобы использовать правильное значение члена объекта.
Если ваш объект не является связанные с безопасностью потоков, тогда нет никаких оснований указывать, какое значение имеет значение члена объекта.
Ответ @William Brendel предоставил три разных варианта использования красивым способом.
Использовать случай 1:
В документации по документации java на этот предоставляет те же варианты использования.
Внутри метода экземпляра или конструктора это ссылка на текущий объект - объект, чей метод или конструктор вызывается. Вы можете обратиться к любому члену текущего объекта из метода экземпляра или конструктора, используя это.
blockquote>Он охватывает два примера:
Используя это с полем и Используя это с конструктором
Используйте случай 2:
Другой вариант использования, который имеет не цитируется в этом сообщении:
this
может использоваться для синхронизации текущего объекта в многопоточном приложении для защиты критического раздела данных & amp; методы.synchronized(this){ // Do some thing. }
Использовать случай 3:
Реализация шаблона Builder зависит от использования
this
для возврата измененный объект.См. этот пост
Сохранение строителя в отдельном классе (свободный интерфейс)
Ниже приведены способы использования этого ключевого слова в java:
this
для ссылки на текущие переменные экземпляра класса this()
для вызова конструктор текущего класса this
для возврата текущего экземпляра класса this
в качестве параметра метода https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
this
является ссылкой на текущий объект. Он используется в конструкторе для различения локальной и текущей переменных класса, имеющих одно и то же имя. например ::
public class circle {
int x;
circle(int x){
this.x =x;
//class variable =local variable
}
}
this
также может использоваться для вызова одного конструктора из другого конструктора. например:
public class circle {
int x;
circle() {
this(1);
}
circle(int x) {
this.x = x;
}
}