Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 纯方法必须是静态的吗?_Java_Semantics - Fatal编程技术网

Java 纯方法必须是静态的吗?

Java 纯方法必须是静态的吗?,java,semantics,Java,Semantics,目前我正在阅读一本教科书,它将纯方法定义为: “一种只依赖其参数而不依赖其他数据的静态方法” 如果实例方法不是静态的(只要它不修改参数,也不具有打印等“副作用”),那么它就不可能是纯方法吗 我知道,对于纯方法来说,返回值只取决于参数,而不取决于任何其他状态,因此,调用实例方法的方式可能意味着从调用该方法的对象获取的变量不算作参数,而是算作另一个“状态” 除此之外,我想不出为什么非静态方法不能成为纯方法 下面是一个例子: public class Rational { private i

目前我正在阅读一本教科书,它将纯方法定义为:

“一种只依赖其参数而不依赖其他数据的静态方法”

如果实例方法不是静态的(只要它不修改参数,也不具有打印等“副作用”),那么它就不可能是纯方法吗

我知道,对于纯方法来说,返回值只取决于参数,而不取决于任何其他状态,因此,调用实例方法的方式可能意味着从调用该方法的对象获取的变量不算作参数,而是算作另一个“状态”

除此之外,我想不出为什么非静态方法不能成为纯方法

下面是一个例子:

public class Rational {

    private int numer;
    private int denom;

    public Rational() {
        this.numer = 0;
        this.denom = 1;
    }

    public Rational(int numer, int denom) {
        this.numer = numer;
        this.denom = denom;
    }
}
上面定义了一个
Rational

然后,您可以在
Rational
类中编写一个方法,通过下面的“方法一”或“方法二”将
Rational
对象作为
double
返回

方法一:

public double toDouble() {
    double x = this.numer;
    double y = this.denom;
    double fprat = x / y;
    return fprat;
}   
方法二:

public static double toDouble(Rational rational)
{
    double x = rational.numer;
    double y = rational.denom;
    double fprat = x / y;
    return fprat;
} 
它们本质上做完全相同的事情,但一个是静态方法,另一个是实例方法,因此它们的调用将采用不同的格式。方法二当然是一种纯方法,但在这种情况下,非静态的方法一也会被定义为纯方法吗?

“纯”基本上意味着“只依赖于它的参数,没有副作用”

静态方法不必是纯的,因为它可能访问静态数据结构。同样,实例方法可能是纯的,因为它不访问任何实例变量

因此,“静态”和“实例”的概念与“纯”的概念没有直接关系。

纯方法也可以是静态的。纯方法的两个标准是:

  • 如果给定相同的值,该函数总是计算相同的结果值 参数值。函数结果值不能依赖于任何 执行程序时可能会更改的隐藏信息或状态 继续执行或在程序的不同执行之间执行,也不能 依赖于来自I/O设备的任何外部输入

  • 对结果的评估不会导致任何语义上的可观察性 副作用或输出,如可变对象或输出的突变 连接到I/O设备

  • (强调矿山)

    没有理由认为这不能应用于非静态方法。将该方法设置为静态将为调用方提供更有力的保证,即没有使用实例状态,因此最好将其设置为静态


    根据您的视角,可以将实例方法简单地视为一个带有额外隐式参数的函数:实例本身。通过这种方式,非静态方法可以依赖于实例状态并被视为纯方法,前提是它不依赖于任何外部状态(单例等)或产生副作用。这取决于解释,但我个人的观点是,这种方法是纯粹的

    把它巧妙地写在评论中:

    为什么认为隐藏的this指针比 该函数还有其他参数吗?这一论点导致了一场争论 矛盾:假设
    publicstaticintpurefunc(myinstanceself)
    是纯的,显然是同构的
    public int pureFunc()
    将作为 嗯

    该定义的“静态”部分是多余的。静态方法不能保证它不依赖于任何其他状态。我怀疑该定义只是想确保该方法不使用实例变量

    另一方面,从技术上讲,您也可以将实例方法视为具有第零个参数(对象本身)的静态方法。如果该对象是不可变的(或者该方法没有改变对象中的任何内容),您可以认为该方法仍然是纯的。基本上,您将“对象”视为一个附加参数

    例如,在Java中,可以这样做,使第一个参数成为调用该方法的对象本身。

    此方法:

    public int add(int a, int b) {
       return a + b;
    }
    
    不是静态的,但其返回值不依赖于除参数以外的任何内容。但是正因为如此,
    add
    根本不需要是一个实例方法

    我认为这就是你的教科书所得到的——不访问状态或改变状态的实例方法也可能是静态的


    实例方法应该依赖于对象的状态,否则它应该是静态方法。不依赖于静态的静态方法是纯粹的。

    从概念上讲,静态方法和实例方法之间的唯一区别是实例方法有一个隐藏参数,可以通过
    这个
    关键字访问

    因此,如果一个实例方法不变异
    this
    ,那么它就是纯静态方法


    这里的问题可能与虚拟调度有关,而虚拟调度是由
    静态
    阻止的。基类方法可能是纯的,而派生类方法可能是不纯的,因为它们在Java类型系统中的契约是相等的。

    不能保证
    静态方法是
    纯的。从技术上讲,静态方法可以具有静态。
    这就是你的假设的原因

    “仅依赖其参数而不依赖其他数据的静态方法”

    事实并非如此

    编辑 在Bergi评论之后

    如前所述,
    static
    关键字不能保证无状态。 如果您在报价中省略了
    static
    关键字,它仍然是真的

    所以回答你的问题。纯方法必须是静态的吗?答案是视情况而定

    将纯函数设置为静态会带来好处,即:

    • 这是一个自我检查,它保证您不会(意外地)更改类中的状态