Java 约定:在编写方法时,我应该返回值,还是直接更改数据?

Java 约定:在编写方法时,我应该返回值,还是直接更改数据?,java,python,methods,return,conventions,Java,Python,Methods,Return,Conventions,我已经编写Java和Python代码一段时间了。我已经注意到,很多次,两种语言中的对象调用其方法的方式似乎不一致。以这些Python代码片段为例。(语法并不重要,只需注意方法处理数据的方式) 与: class Bar(object): def __init__(self, num = 0): self.num = num def __str__(self): return str(num) def addOne(self):

我已经编写Java和Python代码一段时间了。我已经注意到,很多次,两种语言中的对象调用其方法的方式似乎不一致。以这些Python代码片段为例。(语法并不重要,只需注意方法处理数据的方式)

与:

class Bar(object):
    def __init__(self, num = 0):
        self.num = num

    def __str__(self):
        return str(num)

    def addOne(self):
        return Bar(num + 1)

if __name__ == "__main__":
    bar = Bar()
    print(bar) # Outputs 0

    bar.addOne()
    print(bar) # Still Outputs 0

    bar = bar.addOne()
    print(bar) # Now Outputs 1

这两个示例非常相似,但是当调用Foo.addOne()时,Foo类会更改类内的num变量。但是,Bar类的addOne()方法返回一个更新了num变量的新对象。哪种情况在什么时候更可取,人们期望什么,不同语言之间的差异是否很大

Java具有某些不可变的类。您(作为Java开发人员)也可以创建这样的类。即使您愿意,也无法从不可变类更改任何对象的内部状态(例如,如果不创建新的
Integer
对象,则无法将1添加到
Integer
对象,如果不创建新的
String
对象,则无法将“a”附加到String对象,即使您愿意)


现在,如果一个类不是不可变的,您可以自由地采用这两种方法(更改现有实例的内部状态,或者创建一个新实例)。但是无论你采取哪种方法,你都应该记录下来,这样你的呼叫者就知道会发生什么。至少就我所知,这就是它在Java世界中的工作方式

简单回答:没有这样的惯例。作为一种语言,Python结合了面向对象和函数范式。就我个人而言,对于Python开发人员来说,在每个特定情况下选择哪一个是最微妙的技能

你应该回答很多问题,例如,你的物品应该如何使用?它会在线程之间共享吗?性能是一个问题吗?应用程序架构的约定是什么?也许答案以后会改变,所以请做好重构的准备

Python的限制性比Java小得多,并且不能保证对象的状态。它既不能像Java那样假设执行低级性能优化。因此,“可变”/“不可变”的定义仅仅是Python类的约定。与其说是语言的技术特征,不如说是我们如何理解对象


在一般情况下(或有疑问的情况下),我建议遵循规则并坚持共同的模式。例如,如果对象的行为类似于字符串,则返回新实例;如果像字典一样,执行就地修改。极端情况通常是错误的,好的Python设计使用两个世界中最好的一个。

如果您只想增加,为什么要返回一个新对象?问题是,您想增加(更改对象)还是需要一个新对象?如果可以避免冗余对象,您可能会避免返回新对象。如果方法(例如,处理方法)可能会修改传递给它的对象的状态,则会导致它返回上下文。@user1767754抱歉,这是一个坏例子,这在实际系统中是无用的。但是,这是一个例子,但是整数将在它的作用域中临时创建,不是吗?@user1767754我不明白你的意思。
class Bar(object):
    def __init__(self, num = 0):
        self.num = num

    def __str__(self):
        return str(num)

    def addOne(self):
        return Bar(num + 1)

if __name__ == "__main__":
    bar = Bar()
    print(bar) # Outputs 0

    bar.addOne()
    print(bar) # Still Outputs 0

    bar = bar.addOne()
    print(bar) # Now Outputs 1