java中的final类是不是与所有方法都声明为final且所有变量都声明为private的类相同[重复]

Posted

技术标签:

【中文标题】java中的final类是不是与所有方法都声明为final且所有变量都声明为private的类相同[重复]【英文标题】:Is final class in java same as a class with all methods declared as final and all variables declared as private [duplicate]java中的final类是否与所有方法都声明为final且所有变量都声明为private的类相同[重复] 【发布时间】:2020-03-24 07:12:04 【问题描述】:

我正在研究 java 中 final 类的概念,它说 final 类不能在 java 中被继承。但是,如果我们可以将class的所有方法都设为final,所有变量都设为private,是不是和将class声明为final的效果一样?

假设以下场景:

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

我们是否可以通过将类的所有方法设置为 final 并将所有变量声明为 private 和 final 来实现这种不变性要求,以实现这种不变性条件?

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

【问题讨论】:

没有。您可以将所有变量和方法都声明为 final 的类,这不会阻止您对它进行子类化。 这不会阻止您创建一个继承自该类并添加新方法的类 是的,它不会阻止子类化,但是该子类是否能够以任何方式影响超类,如果超类被声明为 final,这是不可能的?我在这里谈论的是影响,而不是我们能否继承。 【参考方案1】:

没有。创建一个类final 和创建它的变量和方法final 是不同的东西。

当你创建一个类final时,它不能被子类化。这就是final 对课程的全部意义。 final 类可以有非final 变量(但它的方法隐式为final,是的)。示例:

final class Foo 
    private int counter;

    public int increment() 
        return ++this.counter;
    

当您创建一个方法final 时,它不能在子类中被覆盖。当你创建一个变量final 时,它不能被修改。即使一个类的所有变量和方法都是finalclass 仍然可以被子类化,并且仍然可以添加新方法。示例:

class Foo 
    public final void method1() 
        System.out.println("method1");
    

class SubFoo extends Foo 
    public void method2() 
        System.out.println("method2");
    


是您相当重要的编辑:

我们是否可以通过将类的所有方法设为 final 并将所有变量声明为私有来实现这种不变性要求,以实现这种不变性条件?

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

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;
    

【讨论】:

我真的觉得没什么问题 @TJCrowder 你现在能回答这个问题吗,我认为你已经很好地解释了 final 关键字的使用,但是在最新的编辑中,我的问题更多地是关于类概念的 final 和不变性。跨度> @aquesh - 已更新。不过,如果可以的话,最好避免进行那么大的更改。 @aquesh - 如果您对SubFoo 的引用属于Foo 类型,那么确实通过该引用您无法更改任何内容。但是,这并不能使对象不可变。这只是意味着它的Foo 部分是不可变的。 这很好解释,感谢@T.J.Crowder 总结一下:SubFoo 是可变的(尽管它的超类部分是不可变的)。通过 Foo 引用创建的任何对象, Foo obj = new Foo(10) 始终是不可变的

以上是关于java中的final类是不是与所有方法都声明为final且所有变量都声明为private的类相同[重复]的主要内容,如果未能解决你的问题,请参考以下文章

java中 终极类

Java——面向对象进阶(final关键字,static关键字,匿名对象,内部类,包的声明与访问,四种访问修饰符,代码块)

final 关键字与安全发布 多线程中篇(十三)

在Java JVM里,如果一个变量被声明为final或者static, 那么这个变量的引用以及它的值被存放在哪?

Java接口与抽象类的区别

四月二十日java基础知识