Использование «this» с методами (в Java) - PullRequest
12 голосов
/ 05 февраля 2009

как насчет использования "this" с методами в Java? Это необязательно или есть ситуации, когда его нужно использовать обязательно?

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

public class Test {

    String s;

    private String hey() {
        return s;
    }

    public String getS(){
        String sm = this.hey();
        // here I could just write hey(); without this
        return sm;
    }
}

Ответы [ 7 ]

33 голосов
/ 05 февраля 2009

Три очевидных ситуации, когда это нужно:

  • Вызов другого конструктора из того же класса, что и первая часть вашего конструктора
  • Различение локальной переменной и переменной экземпляра (в конструкторе или любом другом методе)
  • Передача ссылки на текущий объект другому методу

Вот пример всех трех:

public class Test
{
    int x;

    public Test(int x)
    {
        this.x = x;
    }

    public Test()
    {
        this(10);
    }

    public void foo()
    {
        Helper.doSomethingWith(this);
    }

    public void setX(int x)
    {
        this.x = x;
    }
}

Я полагаю, что есть также некоторые странные ситуации, в которых используются внутренние классы, где вам нужно super.this.x, но их следует избегать, так как они очень запутаны, ИМО:)

РЕДАКТИРОВАТЬ: Я не могу вспомнить ни одного примера, почему вы хотели бы это для прямого this.foo() вызова метода.

РЕДАКТИРОВАТЬ: saua внесла это в отношении неясных примеров внутреннего класса:

Я думаю, что неясный случай: OuterClass.this.foo() при доступе к foo() внешнего класс из кода во внутреннем классе, который также имеет метод foo().

2 голосов
/ 05 февраля 2009

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

class Foo {
    int val;

    public Foo(int val) {
         this(val, 0);  //this MUST be here to refer to another constructor
    }

    public Foo(int val, int another) {
        val = val;       //this will work, but it generally not recommended.
        this.val = val;  //both are the same, but this is more useful.
        method1();       //in a Foo instance, it will refer to this.method1()
        this.method1();  //but in a Foo2 instance, you must use this to do the same
    }

    public void method1() {}
}

class Foo2 extends Foo {
    public Foo2(int val) {
        this(val);        //this will refer to the other Foo2 constructor
    }
    public Foo2(int val, int another) {
        super(val, another);
        super.method1();   //this will refer to Foo.method1()
    }

    @Override
    public void method1() {}//overridden method
}

Это не все случаи, но некоторые из более общих. Я надеюсь, что это поможет вам лучше понять ключевые слова this и super и как / когда их использовать.

2 голосов
/ 05 февраля 2009

Я использую «это» для пояснения кода, часто в качестве подсказки, что я вызываю метод экземпляра, а не обращаюсь к методу уровня класса или полю.

Но нет. Если не требуется устранения неоднозначности из-за коллизии именования областей, на самом деле вам не нужно "this".

0 голосов
/ 11 февраля 2009

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html

Это абсолютно необходимо, если ваш метод должен вернуть экземпляр объекта.

public class StringBuildable {
    public StringBuildable append(String text) {
        // Code to insert the string -- previously this.internalAppend(text);
        return this;
    }
}

Это позволяет объединять методы следующим образом:

String string = new StringBuildable()
    .append("hello")
    .append(' ')
    .append.("World")
    .toString()
;
0 голосов
/ 11 февраля 2009

Единственная причина для добавления this перед вызовом метода - указать, что вы вызываете нестатический метод. Я не могу придумать какой-либо другой веской причины сделать это (поправьте меня, я ошибаюсь). Я не рекомендую это соглашение, поскольку оно не добавляет особой ценности. Если не применять последовательно, то это может ввести в заблуждение (поскольку вызов метода без этого все еще может быть нестатическим). Как часто заботится, является ли вызываемый метод статическим или нет? Кроме того, большинство IDE по-разному выделяют статические методы.

Я слышал о соглашениях, где this указывает на вызов метода подкласса, в то время как отсутствие this вызывает метод суперкласса. Но это просто глупо, так как конвенция может быть наоборот.

Редактировать : Как отмечает mmyers (см. Комментарий), this работает со статическими методами. При этом я не вижу абсолютно никакой причины, чтобы начинать с this, поскольку это не имеет никакого значения.

0 голосов
/ 05 февраля 2009

Не ответ (так что не стесняйтесь голосовать за него), но я не смог уместить это в комментарии, где кто-то спрашивал.

Многие люди используют "this.x", чтобы визуально отличать переменные экземпляра от локальных переменных и параметров.

Так они и сделали бы:

private int sum;
public int storeSquare (int b) {
    int c=b*b;
    this.sum+=c; // Makes sum "pop" I guess
    return c;
}

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

Делать это с "этим". только 50% безопасно. Конечно, компилятор поймает его, если вы попытаетесь поместить this.x, когда x является локальной переменной, но ничто не помешает вам «забыть» пометить переменную экземпляра этим., И если вы забудете пометить только один (или если кто-то еще работает над вашим кодом), и вы полагаетесь на шаблон, тогда шаблон может быть более разрушительным, чем хорошим

Лично я вполне уверен, что паттерн проистекает из недовольства программистов (законных) тем фактом, что в данном случае:

public void setMe(int me) {
    this.me=me;
}

тот факт, что вам нужно "это". передо мной определяется название параметра - я согласен, он просто чувствует себя неряшливо. Вы хотите быть последовательным - если вам это нужно. передо мной, почему бы не всегда использовать его?

Хотя я понимаю дискомфорт, печатая это. каждое место, где используется переменная экземпляра, просто педантично, бессмысленно, безобразно и ненадежно. Если это действительно беспокоит вас, и вам нужно , чтобы использовать шаблон для его решения, попробуйте поставить "p" перед вашими параметрами. Как побочный эффект, он должен даже сделать его более постоянным, потому что регистр параметра теперь будет соответствовать регистру метода.

public void setMe( int pMe) 
0 голосов
/ 05 февраля 2009

Единственный раз, когда это действительно требуется, это когда у вас есть параметр для метода с тем же именем, что и переменная-член. Лично я стараюсь всегда использовать это, чтобы сделать область действия переменной / метода явной. Например, у вас может быть статический метод или метод экземпляра. При чтении кода может быть полезно узнать, что есть что.

...