【问题标题】:Meaning of "this" in this code?此代码中“this”的含义?
【发布时间】:2017-05-21 10:24:22
【问题描述】:
 public boolean contains(Object o) {
    for (E x : this)
        if (x.equals(o))
            return true;
    return false;
}

谁能告诉我这段代码中的“this”是什么意思?没有这个我可以写吗?怎么写?

【问题讨论】:

  • 简单地说,增强的 for 循环中的第二个参数(: 之后)是任何 Iterable<E>。在这种情况下,您当前的实例(#contains 方法中的this)是Iterable<E> 的实例。
  • 这里可能有2个问题-what the E x : ... for-loop does,然后是what the this refers to(以及如何在没有this的情况下重写它,如果你理解代码应该会很明显)
  • 尴尬。我想作为副本关闭,但是 2010 年的候选副本没有接受的答案...:/ .

标签: java oop


【解决方案1】:

这里this 表示调用当前方法的对象。例如,如果您有a.contains(x),那么在contains 方法中this 将返回对与a 引用变量中保存的相同对象的引用。

由于您知道在 for-each 中可以使用 this,这意味着 contains 方法被放置在实现 Iterable<E> 接口的类中,因为 for-each 只能迭代:

  • String[] array = ...; for(String s : array){...}这样的数组
  • 实现Iterable<E> 的类的实例,例如List<String>,我们可以在其中编写for(String s : list){...}

为避免this,您可以显式添加包含此方法的类的方法参数,例如

public boolean contains(YourClass yc, Object o) {

//and use that parameter in loop instead of `this`

    for (E x : yc)
        if (x.equals(o))
            return true;
    return false;
}

但这意味着您需要以a.contains(a,x) 的方式调用此类方法,因此它需要重复a 两次(更不用说它可以让我们传递除a 之外的其他类实例,例如@987654340 @)。

为了避免这种重复,我们可以创建contains 方法static,这将允许通过YourClass.contains(a,x) 调用它。但是这种方式我们需要放弃基本的 OOP 概念之一——多态性——因为它不适用于 static 方法。

编译器使用第一个解决方案解决它,因此它编译我们的方法就像它们将被编写(并且我们实际上可以这样编写方法)为

public boolean contains(YourClass this, Object o) {
//                      ^^^^^^^^^^^^^^
    ...
}

然后,当我们编写 a.contains(x) 时,它的编译就像我们调用 a.contains(a,x) 一样。

【讨论】:

  • 对参数列表中包含的 this 参数的主要支持。不知道你能做到这一点
  • @Rogue 我相信,与许多事情一样,它是针对 C 限制的 C++ 解决方法的 Java 简化。长话短说,在 C++ 中,编译器本质上将成员函数转换为独立函数,其中 this 是隐式传递的第一个参数;给定类类型class C { public: void f() {} }; 和实例C c,编译器本质上会将成员C::f() 转换为独立的void C_f(C* const this) {},并将c.f() 调用为C_f(&c)。与 C++ 不同,Java 似乎允许程序员在参数列表中手动指定this
  • (这是因为原来的C++编译器实际上将C++代码交叉编译成C代码。由于C不允许structs有成员函数,C++编译器不得不把它们变成独立的函数;因为它们需要绑定到特定实例,所以它们必须将该实例作为参数(必须将其实现为指针,既因为 C 没有引用,又因为我不相信引用是直到this'语法最终确定之后才添加到语言中)。它最终看起来像this。)
  • (虽然名称会比 C::f 变成 C_f 更复杂,但名称修改与此无关。)
  • 哇,我不知道您可以将this 作为参数显式传递。有一个解释here为什么存在这个功能:允许this的注解。
【解决方案2】:

this 是包含contains() 方法的类的对象。它指的是为其执行方法的那个类的对象。

将它放在增强 for 循环的 : 之后意味着包含此方法的类必须实现 Iterable<E>,因为增强的 for 循环可用于遍历数组或实现 @ 的类的实例987654325@接口。这意味着您的类能够迭代一些E 元素的集合。 E 可能是泛型类型参数`。

为了在没有this 的情况下编写您的方法,您必须提供对实现Iterable<E> 的替代对象的引用,但我看不出这样做的意义。

【讨论】:

    【解决方案3】:

    这段代码中的this到底是什么意思?

    它始终是对当前实例的引用。我假设您的类实现了Iterable<T> 接口并覆盖了Iterator<T> iterator() 方法。

    循环只是增强的for 语句的语法糖。根据规范(§14.14.2.):

    for ({VariableModifier} UnannType VariableDeclaratorId : Expression)
        Statement
    

    Expression 的类型必须是 Iterable 或数组类型(第 10.1 节),否则会发生编译时错误。

    如果Expression的类型是Iterable的子类型,那么翻译如下。

    如果Expression的类型是Iterable<X>的子类型,对于某个类型参数X,那么让I成为java.util.Iterator<X>的类型;否则,让I 为原始类型Iterator

    增强的 for 语句相当于基本的 for 语句,形式如下:

    for (I #i = Expression.iterator(); #i.hasNext(); ) {
        {VariableModifier} TargetType Identifier = (TargetType) #i.next();
        Statement
    }
    

    通常,一个类实现 Iterable 以向 API 用户提供允许迭代隐藏实际实现的内部集合的能力。

    没有这个我可以写吗?如何写?

    1. 使用您为内部迭代器编写的逻辑。
    2. 使用底层集合的实现(如果合适的话)。
    3. 选择上述选项之一并重写为标准for

    【讨论】:

      【解决方案4】:

      关键字this 只是对当前对象的引用。

      这是一个如何使用this 的示例:

      public class Person {
          public final String name;
      
          public Person(String name) {
              // name = name; 
              // which one is an argument, and which one is class field? 
              // by default, both are reference on argument
      
              // using "this" to access class field
              this.name = name;
          }
      
          public void copyFields(Person other) {
              // current object's reference is the same as other object reference 
              // in other words "this" and "other" are the same instances 
              // example: 
              // Person p1 = new Person("a");
              // Person p2 = p1; // p2 is now pointing on the same memory address
              //                 // as p1, so both are pointing on the same object
              //                 // stored in memory.
              // p1.copyFields(p2);
              if (this == other) { // copying from self? useless...
                  return;
              }
              this.name = other.name;
          }
      }
      

      任何实现Iterable 接口的方法都有返回Iterator 实例的方法,foreach 循环隐式使用该方法来迭代对象持有的项目。迭代器 有方法hasNext(),如果有另一个对象,则返回true 在可迭代容器中,相对于当前位置,next() 返回 如果没有下一个对象,则下一个 object 或抛出 NoSuchElementException(最后一次调用 hasNext() 已返回 false)。

      这是一个使用contains 方法实现Iterable 的简单示例:

      public class Customer extends Person implements Iterable<Item> {
          private final List<Item> list = new LinkedList<>();
          public final String name;
      
          public Customer(String name) {
              this.name = name;
          }
      
          public void add(Item item) {
              list.add(item);
          }
      
          // implementing iterable interface
      
          @Override
          public Iterator<Item> iterator() {
              return list.iterator();
          }
      
          // some contains implementations
      
          public boolean contains1() {
              for (Item item : this) { // customer implements Iterable = OK
                  if (o.equals(item)) {
                      return true;
                  }
              }
              return false;
          }
      
          public boolean contains2() {
              for (Item item : list) { // list implements Iterable = OK
                  if (o.equals(item)) {
                      return true;
                  }
              }
              return false;
          }
      
          public boolean contains3(Object o) {
              for (Iterator<Item> iter = iterator(); iter.hasNext();   ) {
                  Item item = iter.next();
                  if (o.equals(item)) {
                      return true;
                  }
              }
              return false;
          }
      
          public boolean contains4(Object o) {
              for (Iterator<Item> iter = list.iterator(); iter.hasNext();   ) {
                  Item item = iter.next();
                  if (o.equals(item)) {
                      return true;
                  }
              }
              return false;
          }
      
          public boolean contains5(Object o) {
              Iterator<Item> iter = iterator(); 
              while (iter.hasNext()) {
                  Item item = iter.next();
                  if (o.equals(item)) {
                      return true;
                  }
              }
              return false;
          }
      
          public boolean contains6(Object o) {
              Iterator<Item> iter = list.iterator();
              while (iter.hasNext()) {
                  Item item = iter.next();
                  if (o.equals(item)) {
                      return true;
                  }
              }
              return false;
          }
      
          public boolean contains7(Object o) {
              return list.contains(o);
          }
      }
      

      【讨论】:

        【解决方案5】:

        方法是在 classes 中定义的,而不是在 objects 中定义的。

        但它们(通常)是从 objects 调用的。

        方法 - 正如它们在 classes 中定义的那样 - 事先不知道 哪个对象会调用它们


        所以有一种机制(由隐藏参数this 实现),通过该机制,对象在调用方法时会秘密地将自身的地址传递给参数this

        (在其他编程语言中可能会使用other名称,如Meself。)

        【讨论】:

          【解决方案6】:

          我会为你加分

          1. 当我们创建一个类的新实例时,非静态方法和非静态成员字段就是它的一部分。我们使用. 运算符访问这些方法和字段。

          2. 所有非静态方法或成员字段都可以访问thisthis 关键字只是对执行该方法的当前对象的引用。

          3. 任何实现Iterable 接口的类都可以与增强的For-Loop 一起使用。

          4. 增强的 for 循环使用语法

          for (Object object : objectOfIterableType)

          如果实现Iterable接口的类被参数化,假设它的E。那么它就是你在你的代码中必须要做的。

              for (E x : this)
          
          1. 这意味着当前类具有可迭代的行为,并且可以对其持有的项目集合进行迭代。上述语句将针对由 this 关键字引用的当前对象表示的 E 类型项目集合中的每个项目执行。在每次迭代中,x 将代表那些包含的项目中的一个项目。

          【讨论】:

            猜你喜欢
            • 2014-03-26
            • 2017-02-23
            • 2010-11-03
            • 1970-01-01
            • 2010-11-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-06
            相关资源
            最近更新 更多