标签: final

为什么内部类可以覆盖私有final方法?

我想知道将私有方法声明为最终是否有意义,我认为这没有意义.但我想象有一个独特的情况,并编写代码来弄清楚:

public class Boom {

    private void touchMe() {
        System.out.println("super::I am not overridable!");
    }

    private class Inner extends Boom {

        private void touchMe() {
            super.touchMe();
            System.out.println("sub::You suck! I overrided you!");
        }
    }

    public static void main(String... args) {
        Boom boom = new Boom();
        Boom.Inner inner = boom.new Inner();
        inner.touchMe();
    }
}
Run Code Online (Sandbox Code Playgroud)

它编译和工作."我应该让touchMe()最终成功"我想到并做到了:

public class Boom {

    private final void touchMe() {
        System.out.println("super::I am not overridable!");
    }

    private class Inner extends Boom {

        private void touchMe() {
            super.touchMe();
            System.out.println("sub::You suck! I …
Run Code Online (Sandbox Code Playgroud)

java overriding final inner-classes

66
推荐指数
3
解决办法
3883
查看次数

使用try/catch进行最终变量赋值

因为我认为这是一个很好的编程实践,所以final如果它们只打算编写一次,我会创建所有(本地或实例)变量.

但是,我注意到当变量赋值可以抛出异常时,你不能使变量最终变为:

final int x;
try {
    x = Integer.parseInt("someinput");
}
catch(NumberFormatException e) {
    x = 42;  // Compiler error: The final local variable x may already have been assigned
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在不诉诸临时变量的情况下做到这一点?(或者这不是最终修饰符的正确位置?)

java final

64
推荐指数
1
解决办法
2万
查看次数

最终的ArrayList是什么意思?

通过使ArrayList(或其他Collection)最终获得哪些优点/缺点?我仍然可以添加ArrayList新元素,删除元素并更新它.但是什么影响使它成为最终的?

java final arraylist

61
推荐指数
5
解决办法
6万
查看次数

"final int i"如何在Java for循环中工作?

我很惊讶地发现以下Java代码片段已编译并运行:

for(final int i : listOfNumbers) {
     System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud)

其中listOfNumbers是一个整数数组.

我认为最终的声明只分配了一次.编译器是否创建了Integer对象并更改了它引用的内容?

java final

60
推荐指数
2
解决办法
1万
查看次数

最终瞬态场和序列化

final transient在Java中进行序列化后,是否可以将字段设置为任何非默认值?我的用例是一个缓存变量 - 这就是它的原因transient.我也习惯于制作Map不会改变的字段(即地图的内容被改变,但是对象本身保持不变)final.但是,这些属性似乎是矛盾的 - 虽然编译器允许这样的组合,但我不能将字段设置为除了反null序列化之外的任何东西.

我尝试了以下内容,没有成功:

  • 简单字段初始化(在示例中显示):这是我通常所做的,但是在反序列化之后似乎没有发生初始化;
  • 在构造函数中初始化(我相信这在语义上与上面相同);
  • 分配字段readObject()- 因为字段是,所以无法完成final.

在该示例cachepublic仅用于测试.

import java.io.*;
import java.util.*;

public class test
{
    public static void main (String[] args) throws Exception
    {
        X  x = new X ();
        System.out.println (x + " " + x.cache);

        ByteArrayOutputStream  buffer = new ByteArrayOutputStream ();
        new ObjectOutputStream (buffer).writeObject (x);
        x = (X) new ObjectInputStream (new ByteArrayInputStream (buffer.toByteArray ())).readObject ();
        System.out.println …
Run Code Online (Sandbox Code Playgroud)

java serialization final

59
推荐指数
4
解决办法
2万
查看次数

为什么在Java中将局部变量和方法参数标记为"final"?

在Java中,您可以使用final关键字限定局部变量和方法参数.

public static void foo(final int x) {
  final String qwerty = "bar"; 
}
Run Code Online (Sandbox Code Playgroud)

这样做会导致无法在方法体中重新分配x和qwerty.

这种做法使你的代码向不变性的方向推动,这通常被认为是一个加分.但是,它也会使代码混乱,"最终"出现在各处.您对Java中的局部变量和方法参数的final关键字有何看法?

java final

57
推荐指数
5
解决办法
10万
查看次数

为什么声明一个函数参数是最终的?

我目前正在通过Sams出版的"24小时自学Android应用程序开发"一书.我对Java,Android或其他方面比较陌生.我在ActionScript 3中有一个非常扎实的背景,它与Java有足够的相似之处,语言本身并不难理解,但我仍然对本书中某些代码示例背后的基本原理有一些疑问.例如,这是第9小时的示例代码附带的函数:

private void processScores(final TableLayout scoreTable, 
      XmlResourceParser scores) throws IOException, XmlPullParserException{
Run Code Online (Sandbox Code Playgroud)

在此函数签名中,作者已将scoreTable参数声明为final.我有点不解为什么他们这样做了.即使尝试为函数参数scoreTable分配一个新值,也不会让我想到这一点(在ActionScript中它被认为是一种不好的做法).此外,我还没有看到任何人在我检查或移植到AS3中的任何真实Java中都这样做.

有没有关于Android开发的具体内容,有时需要将某些函数参数声明为final?

为什么TableLayout对象声明为final,而不是XmlResourceParser?

java android final

56
推荐指数
1
解决办法
3万
查看次数

可以在catch中重新分配最终变量,即使赋值是try中的最后一个操作吗?

我相信这里

final int i;
try { i = calculateIndex(); }
catch (Exception e) { i = 1; }
Run Code Online (Sandbox Code Playgroud)

i如果控制到达catch-block,则可能无法分配.但是,Java编译器不同意并声称the final local variable i may already have been assigned.

我还缺少一些细微之处,或者这只是Java语言规范用于识别潜在重新分配的模型的弱点?我的主要担心是这样的事情Thread.stop(),这可能会导致异常被"凭空捏造"抛出,但我仍然看不到它如何在赋值后抛出,这显然是try-block中的最后一个动作.

如果允许,上面的成语将使我的许多方法更简单.请注意,此用例具有一流的语言支持,例如Scala,它始终使用Maybe monad:

final int i = calculateIndex().getOrElse(1);
Run Code Online (Sandbox Code Playgroud)

我认为这个用例是一个非常好的动机,允许一个特殊情况 肯定i是在catch块中未分配.

UPDATE

经过一番思考后,我更加确定这只是JLS模型的一个弱点:如果我在所提出的例子中声明了公理,i当控制到达catch-block时肯定是未分配的",它将不会与任何其他公理冲突或定理.编译器i在catch块中分配之前不允许任何读取,因此i无法查看是否已分配的事实.

java final language-design try-catch

56
推荐指数
4
解决办法
3185
查看次数

为什么尝试打印未初始化的变量并不总是导致错误消息

有些人可能会发现它类似于SO问题Java Final变量是否具有默认值?但是这个答案并没有完全解决这个问题,因为这个问题并没有直接在实例初始化程序块中打印x的值.

当我尝试在实例初始化程序块内直接打印x时,问题出现了,同时在块结束之前为x分配了一个值:

情况1

class HelloWorld {

    final int x;

    {
        System.out.println(x);
        x = 7;
        System.out.println(x);    
    }

    HelloWorld() {
        System.out.println("hi");
    }

    public static void main(String[] args) {
        HelloWorld t = new HelloWorld();
    }
}
Run Code Online (Sandbox Code Playgroud)

这给出了编译时错误,指出变量x可能尚未初始化.

$ javac HelloWorld.java
HelloWorld.java:6: error: variable x might not have been initialized
        System.out.println(x);
                           ^
1 error
Run Code Online (Sandbox Code Playgroud)

案例2

我没有直接打印,而是调用一个打印功能:

class HelloWorld {

    final int x;

    {
        printX();
        x = 7;
        printX();
    }

    HelloWorld() {
        System.out.println("hi");
    }

    void printX() {
        System.out.println(x);
    }

    public static void …
Run Code Online (Sandbox Code Playgroud)

java final initialization

55
推荐指数
2
解决办法
5865
查看次数

为什么Java编译器不能理解这个变量总是被初始化?

class Foo{
    public static void main(String args[]){
        final int x=101;

        int y;
        if(x>100){
            y=-1;
        }
        System.out.println(y);
    }
}
Run Code Online (Sandbox Code Playgroud)

Java编译器理解if语句的条件始终为true,因此将始终初始化y.没有编译错误,如预期的那样.

class Bar{
    public static void main(String args[]){
        final int x;
        x=101;

        int y;      
        if(x>100){
            y=-1;
        }
        System.out.println(y);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我将x的声明和初始化分成两行时,编译器似乎并不认为条件总是为真,并且y将始终被初始化.

final int x;
x=101;
byte b;
b=x;
System.out.println(b);
Run Code Online (Sandbox Code Playgroud)

这里发生了同样的事情,编译器会丢失精度错误.

final int x=101;
byte b;
b=x;
System.out.println(b);
Run Code Online (Sandbox Code Playgroud)

同样,编译器可以理解x在b的范围内.

java conditional final initialization

54
推荐指数
3
解决办法
3065
查看次数