这段代码中“this”的含义是什么?
public boolean contains(Object o) { for (E x : this) if (x.equals(o)) return true; return false; }
有人可以告诉我这段代码中有什么令人兴奋的意思吗? 没有这个可以写它怎么样?
这里表示调用当前方法的对象。 例如,如果你有a.contains(x)
那么在contains
方法中, this
将返回对引用变量中保存的同一对象a
引用。
由于你可以在for-each中使用它,这意味着contains
方法被放置在实现Iterable
接口的类中,因为for-each只能遍历:
- 像
String[] array = ...; for(String s : array){...}
String[] array = ...; for(String s : array){...}
- 实现
Iterable
的类的实例,如List
,我们可以for(String s : list){...}
编写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.contains(b,x)
一样a.contains(b,x)
)。
为了避免这种重复,我们可以使contains
方法static
,允许通过YourClass.contains(a,x)
调用它。 但是这样我们需要从一个基本的OOP概念 – 多态 – 中辞职,因为它不适用于static
方法。
编译器使用第一个解决方案来解决它,因此它编译我们的方法就像编写它们一样(我们实际上可以用这种方式编写方法)
public boolean contains(YourClass this, Object o) { // ^^^^^^^^^^^^^^ ... }
然后,当我们编写a.contains(x)
它被编译为好像我们将调用a.contains(a,x)
。
this
是包含contains()
方法的类的对象。 它指的是执行该方法的该类的对象。
将它放在增强的for循环之后意味着包含此方法的类必须实现Iterable
,因为增强的for循环可用于迭代实现Iterable
接口的类的数组或实例。 这意味着您的类能够迭代一些E
元素集合。 E
可能是generics类型参数`。
为了在没有this
情况下编写你的方法,你必须提供一个实现Iterable
替代对象的引用,但我没有看到这样做的意义。
在这段代码中究竟意味着什么?
它始终是对当前实例的引用。 我假设您的类实现了Iterable
接口并从中覆盖了Iterator
方法。
循环只是增强for
语句的语法糖。 根据规范( §14.14.2。 ):
for ({VariableModifier} UnannType VariableDeclaratorId : Expression) Statement
Expression的类型必须是Iterable或数组类型(第10.1节),否则会发生编译时错误。
如果
Expression
的类型是Iterable
的子Iterable
,则转换如下。如果
Expression
的类型是某个类型参数X
的Iterable
的子类型,那么让I
成为java.util.Iterator
类型; 否则,让I
成为原始类型Iterator
。增强的for语句相当于表单的基本for语句:
for (I #i = Expression.iterator(); #i.hasNext(); ) { {VariableModifier} TargetType Identifier = (TargetType) #i.next(); Statement }
通常,类实现Iterable
以向API用户提供允许迭代隐藏实际实现的内部集合的能力。
没有这个可以写它怎么样?
- 使用您为内部迭代器编写的逻辑。
- 使用底层集合的实现(如果它适合它)。
- 选择上面提到的选项之一并重写为标准。
关键字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循环隐式使用,以迭代对象持有的项目 。 Iterator有方法hasNext()
返回true
,如果在iterable容器中有另一个对象,相对于当前位置, next()
返回下一个object
或抛出NoSuchElementException
如果没有下一个对象( hasNext()
最后一次调用返回false
)。
以下是contains
方法的Iterable
实现的简单示例:
public class Customer extends Person implements Iterable- { private final List
- 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
- 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
- iter = iterator(); iter.hasNext(); ) { Item item = iter.next(); if (o.equals(item)) { return true; } } return false; } public boolean contains4(Object o) { for (Iterator
- iter = list.iterator(); iter.hasNext(); ) { Item item = iter.next(); if (o.equals(item)) { return true; } } return false; } public boolean contains5(Object o) { Iterator
- iter = iterator(); while (iter.hasNext()) { Item item = iter.next(); if (o.equals(item)) { return true; } } return false; } public boolean contains6(Object o) { Iterator
- 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); } }
方法在classes
中定义,而不是在objects
中定义。
但它们(通常)是从objects
调用的。
方法 – 因为它们在classes
中定义 – 事先不知道哪个对象会调用它们 。
因此,有一种机制(由隐藏参数实现),通过该机制,对象 – 在调用方法时 – 秘密地将其自身的地址传递给参数this
。
(在其他编程语言中可以使用其他名称,如Me
或self
。)
我会把它分给你
-
当我们创建一个类的新实例时,非静态方法和非静态成员字段就是它的一部分。 我们使用访问这些方法和字段
.
运营商。 -
所有非静态方法或成员字段都可以访问
this
。this
关键字只是对执行该方法的当前对象的引用。 -
任何实现
Iterable
接口的类都可以与增强的For-Loop
。 -
增强的for循环使用语法
for (Object object : objectOfIterableType)
如果实现Iterable
接口的类被参数化,则假设其为E
那就是你在代码中所拥有的东西。
for (E x : this)
- 这意味着当前类具有可迭代的行为,并且可以在它所拥有的项集合上进行迭代。 将对
this
关键字引用的当前对象表示的类型E的项集合中的每个项执行上述语句。 在每次迭代中,x
将表示包含这些项目的项目。