为什么java中不允许赋值为'this'?

kos*_*tja 20 java reference this variable-assignment

我从编译器得到的错误是"赋值的左侧必须是变量".我的用例是深度复制,但并不真正相关.

在C++中,可以分配给*this.

问题不在于如何规避任务this.这很简单,但是决定不做this变量的背后有什么理由.

原因是技术性的还是概念性的?

我的猜测到目前为止 - 在随机方法中重建Object的可能性容易出错(概念性),但技术上可行.

编辑请限制"因为Java规范如此说"的变化.我想知道决定原因

aio*_*obe 13

在C++中,可以分配给 *this

是的,但你不能this = something用C++ 做,我实际上认为这是你在Java方面所要求的更接近的匹配.

[...]决定不做this变量的原因是什么.

我会说清晰度/可读性.

this被选为保留字,可能因为它不作为方法的显式参数传递.使用它作为普通参数并能够为其重新分配新值会严重损害可读性.

事实上,由于这个原因,许多人认为你根本不应该改变论证变量.

原因是技术性的还是概念性的?

我认为主要是概念性的.但是会出现一些技术怪癖.如果可以重新赋值this,则可以完全隐藏局部变量后面的实例变量.

我的猜测到目前为止 - 在随机方法中重建Object的可能性容易出错(概念性),但技术上可行.

我不确定我是否完全理解这个陈述,但是,容易出错可能是决定将其作为关键词而不是变量的主要原因.


Jig*_*shi 5

因为thisfinal,

this是关键字,而不是变量。并且您不能将某些内容分配给关键字。现在考虑一下它是否是设计规范中的参考变量..并参见下面的示例

并且它保存对对象调用方法的隐式引用。它仅供参考,现在考虑一下您分配了一些东西,this这样不会破坏一切吗?

例子

考虑类中的以下代码String(注意:下面的代码包含编译错误,它只是为了演示 OP 的情况)

   public CharSequence subSequence(int beginIndex, int endIndex) {
      //if you assign something here
       this = "XYZ"  ;
       // you can imagine the zoombie situation here
      return this.substring(beginIndex, endIndex);
   }
Run Code Online (Sandbox Code Playgroud)

  • `this` 甚至不是一个变量。这是一个关键字。 (2认同)
  • @Jigar IMO这个例子不成立——在它的getter中重新分配一个变量并得到意想不到的结果是完全合法的(即使是错误的)。我并不是主张重新分配“this”,只是出于好奇。 (2认同)

Ste*_*n C 5

原因是技术上的还是概念上的?

海事组织,概念上。

this关键字是“参考当前正在执行其方法的对象”手短。您不能更改该对象是什么。在Java执行模型中,这根本没有任何意义。

由于this更改没有意义,因此将其设置为变量是没有意义的。

(请注意,在C ++中,您要分配给*this,而不是this。在Java中,没有*运算符,也没有与之等效的运算符。)


如果您认为可以在飞行中更改方法的目标对象,那么这里有一些反问。

  • 这样做有什么用?(假设的)语言功能会为您解决哪些问题,而这些问题无法用更容易理解的方式解决?

  • 您将如何处理互斥锁?例如,如果您this在同步方法中间分配给...,那么所建议的语义是否有意义?(问题是,您要么在没有锁定的对象上最终以同步方法执行...,要么必须解锁旧对象this并锁定新对象this,这会带来复杂性。此外,如何就旨在实现哪些互斥锁而言,这有意义吗?)

  • 您如何理解这样的事情:

    class Animal {
        foo(Animal other) {
           this = other;
           // At this point we could be executing the overridden
           // Animal version of the foo method ... on a Llama.  
        }
    }
    
    class Llama {
        foo(Animal other) {
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    当然,您可以将此归因于语义,但:

    • 您以一种难以理解的方式破坏了子类的封装,并且
    • 您实际上并没有取得任何特别有用的东西。

如果您认真尝试回答这些问题,我希望您得出的结论是,实施此方法将不是一个好主意。(但是,如果您确实有满意的答案,我建议您将它们写下并发布为您对问题的自己的答案!)

但是实际上,我怀疑Java设计师是否考虑了这个想法,而不仅仅是考虑一下。(正确的是,IMO)


*this = ...C ++ 的形式实际上只是当前对象属性的一系列分配的简写形式。我们已经可以在Java中通过一系列常规分配来做到这一点。当然,不需要新的语法来支持这一点。(一个类从另一个类的状态重新初始化一次的频率是多少?)

我注意到您对此发表了评论:

我想知道的语义是什么this = xy;。您认为应该怎么办?– JimmyB 2011年11月2日在12:18

如果提供的xy是正确的类型,则对此的引用将设置为xy从而使“原始”对象符合gc资格 -kostja 2011年11月2日,12:24

那行不通。

  1. 的值this为(有效)由值传递给该方法被调用的方法时。被呼叫者不知道this引用来自何处。

  2. 即使这样做,那也只是保存引用的地方之一。除非null在所有位置都分配了该对象,否则该对象不能进行垃圾回收。

忽略这在技术上是不可能的事实,我认为您的想法不会有用或无助于编写可读/可维护的代码。考虑一下:

public class MyClass {
    public void kill(MyClass other) {
        this = other;
    }
}

MyClass mine = new MyClass();

....

mine.kill(new MyClass());

// 'mine' is now null!
Run Code Online (Sandbox Code Playgroud)

你为什么想这么做?假设方法名称是无害的,而不是kill,您是否希望该方法能够改变值mine

我不。实际上,我认为这将是一个错误的功能:无用且危险。

即使没有这些令人讨厌的“使其无法访问”的语义,我实际上也看不到任何用于修改的好用例this


归档时间:

查看次数:

9805 次

最近记录:

7 年,10 月 前