java中的final类是否与所有方法都声明为final,所有变量都声明为private的类相同

java中的final类是否与所有方法都声明为final,所有变量都声明为private的类相同,java,inheritance,final,access-modifiers,Java,Inheritance,Final,Access Modifiers,我讨论了java中final类的概念,它说final类不能在java中继承。然而,如果我们可以将类的所有方法都设置为final,将所有变量设置为private,那么它不会产生与将类声明为final相同的效果吗 以以下场景为例: 让我更详细地描述一下我的问题,使类不可变的关键要求之一是-类应该声明为final。所有变量都应该是final(并通过构造函数初始化) 我们可以通过使类的所有方法都是final并将所有变量声明为private和final来实现这个不变性要求吗,以实现这个不变性条件 因此,即

我讨论了java中final类的概念,它说final类不能在java中继承。然而,如果我们可以将类的所有方法都设置为final,将所有变量设置为private,那么它不会产生与将类声明为final相同的效果吗

以以下场景为例:

让我更详细地描述一下我的问题,使类不可变的关键要求之一是-类应该声明为final。所有变量都应该是final(并通过构造函数初始化)

我们可以通过使类的所有方法都是final并将所有变量声明为private和final来实现这个不变性要求吗,以实现这个不变性条件


因此,即使现在可以继承类,我们也不能重写方法(因为方法是最终的),也不能更改超类的变量(因为它们是最终的,也不可见-私有)。

否。使类成为
final
和使其变量和方法成为
final
是不同的事情

当您将类设置为final时,它不能被子类化。这就是
final
对类的所有意义。
final
类可以有非
final
变量(但是它的方法隐式地是
final
,yes)。例如:

final class Foo {
    private int counter;

    public int increment() {
        return ++this.counter;
    }
}
class Foo {
    public final void method1() {
        System.out.println("method1");
    }
}
class SubFoo extends Foo {
    public void method2() {
        System.out.println("method2");
    }
}
当您将方法设置为final时,它不能在子类中被重写。当您将变量设置为final时,它不能被修改。即使一个类的所有变量和方法都是
final
,该类仍然可以被子类化,并且仍然可以添加新的方法。例如:

final class Foo {
    private int counter;

    public int increment() {
        return ++this.counter;
    }
}
class Foo {
    public final void method1() {
        System.out.println("method1");
    }
}
class SubFoo extends Foo {
    public void method2() {
        System.out.println("method2");
    }
}

你的编辑相当重要:

我们可以通过使类的所有方法都是最终的,并将所有变量声明为私有的,来实现这个不变性要求吗

否,因为该类仍然可以被子类化,并且子类可以添加非不变的特性:

class Foo {                 // Immutable
    private final int x;

    public Foo(int x) {
        this.x = x;
    }

    public final int getX() {
        return x;
    }
}

class SubFoo extends Foo {  // NOT immutable, thanks to `y`
    private int y;

    public SubFoo(int x, int y) {
        super(x);
        this.y = y;
    }

    public int getY() {
        return this.y;
    }

    public void setY(int y) {
        this.y = y;
    }
}

不。你可以声明一个包含所有变量和方法的类为final,这不会阻止你对它进行子类化。这不会阻止你创建一个继承自这个类并添加新方法的类是真的,它不会阻止子类化,但该子类能以任何方式影响超类吗,如果超类被宣布为最终类,哪一个是不可能的?我这里说的是影响,而不是我们能否继承。我真的认为没有什么是可以继承的wrong@T.J.Crowder你现在能回答这个问题吗?我想你已经很好地解释了final关键字的用法,但是在最新的编辑中,我的问题更倾向于final&类概念的不变性。@aquesh-已经更新。不过,如果可以的话,最好避免太大的更改。@aquesh-如果您对
subfo
的引用类型为
Foo
,那么通过该引用您确实无法更改任何内容。但这并不能使对象不可变。这仅仅意味着它的
Foo
部分是不可变的。这很好地解释了这一点,感谢@T.J.Crowder总结:subfo是可变的(尽管它的超类部分是不可变的)。通过Foo引用创建的任何对象,Foo obj=new Foo(10)总是不可变的