将函数的参数声明为final:为什么以及何时需要它?

发布于 2024-12-16 17:08:07 字数 244 浏览 0 评论 0原文

在浏览 android 教程(与多线程、循环器和处理程序相关)时,我遇到了这个:

public synchronized void enqueueDownload(final DownloadTask task)

我的问题是:

  1. 何时以及为什么需要将函数的参数声明为最终参数?
  2. 它是 Java 特有的还是 C/C++ 等其他语言中也存在类似的东西?

Going through a tutorial for android (related to multithreading, loopers and handlers), i came across this:

public synchronized void enqueueDownload(final DownloadTask task)

My questions are:

  1. When and why is it needed to declare a parameter of a function as final?
  2. Is it specific to Java or does something similar exist in other languages such as C/C++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

萌︼了一个春 2024-12-23 17:08:07

在 Java 中,通常是这样,这样您就可以访问匿名内部类中的参数 - 这通常在 Android 中用于事件处理程序等。

真正的含义是参数的值不能在方法内更改,但目的通常是针对匿名内部类...

public synchronized void enqueueDownload(final DownloadTask task) {
    SomethingHandler handler = new SomethingHandler() {
        @Override public void handleSomething() {
            // This would not compile if task were not final
            task.doSomething();
        }
    };
    // Use handler
}

In Java this is usually so that you can access the parameter within an anonymous inner class - which is often used in Android for event handlers and the like.

The real meaning is that the parameter's value cannot be changed within the method, but the purpose is usually for anonymous inner classes...

public synchronized void enqueueDownload(final DownloadTask task) {
    SomethingHandler handler = new SomethingHandler() {
        @Override public void handleSomething() {
            // This would not compile if task were not final
            task.doSomething();
        }
    };
    // Use handler
}
旧情勿念 2024-12-23 17:08:07

在您的上下文中,该参数上的final关键字意味着变量task不能在方法体内重新分配,并且它是出于安全原因而指定的。

在 C++ 中可以使用常量函数参数实现类似的行为:

如果您正在编写一个函数并且不打算修改
参数,你可以声明它是一个常量引用参数。

In your context the final keyword on that parameter means that the variable task can't be reassigned inside the method body, and it is specified for security reasons .

A similar behaviour can be achieved in C++ with a constant function parameters :

If you are writing a function and you do not intend to modify a
parameter, you can declare that it is a constant reference parameter.

暮年慕年 2024-12-23 17:08:07

Final 关键字在多个不同的上下文中用作修饰符,这意味着它所修饰的内容在某种意义上无法更改。

Final 类

你会注意到,Java 库中的许多类都被声明为 Final,例如

public Final class String
这意味着此类不会被子类化,并通知编译器它可以执行某些原本无法执行的优化。它还在安全性和线程安全方面提供了一些好处。

编译器不会让您对任何声明为final的类进行子类化。不过,您可能不希望或不需要将自己的类声明为最终类。

Final 方法

您还可以声明方法是 Final 的。声明为 Final 的方法不能在子类中重写。语法很简单,只需将关键字final放在访问说明符之后和返回类型之前,如下所示:

public final String convertCurrency()

final fields

您也可以将字段声明为final。这与将方法或类声明为final 不同。当一个字段被声明为final时,它就是一个不会也不能改变的常量。它可以设置一次(例如,在构造对象时,但此后无法更改。)尝试更改它会生成编译时错误或异常(取决于尝试的狡猾程度)。

最终、静态和公共字段实际上都是命名常量。例如,物理程序可能定义Physics.c,即光速。

public class Physics {

  public static final double c = 2.998E8;


}

在SlowCar 类中,speedLimit 字段可能是最终的和静态的,尽管它是私有的。

public class SlowCar extends Car {

  private final static double speedLimit = 112.65408; // kph == 70 mph

  public SlowCar(String licensePlate, double speed, double maxSpeed,
   String make, String model, int year, int numberOfPassengers, int numDoors) {
    super(licensePlate, 
     (speed < speedLimit) ? speed : speedLimit, 
     maxSpeed, make, model, year, numberOfPassengers, numDoors);
  }

  public void accelerate(double deltaV) {

     double speed = this.speed + deltaV;

     if (speed > this.maxSpeed) {
       speed = this.maxSpeed; 
     }

     if (speed > speedLimit) {
       speed = speedLimit;
     }

     if (speed < 0.0) {
       speed = 0.0; 
     } 

     this.speed = speed;    

  }

}

最终参数

最后,您可以声明方法参数是最终参数。这意味着该方法不会直接更改它们。由于所有参数都是按值传递的,因此这不是绝对必需的,但有时会有帮助。

The final keyword is used in several different contexts as a modifier meaning that what it modifies cannot be changed in some sense.

final classes

You will notice that a number of the classes in Java library are declared final, e.g.

public final class String
This means this class will not be subclassed, and informs the compiler that it can perform certain optimizations it otherwise could not. It also provides some benefit in regard to security and thread safety.

The compiler will not let you subclass any class that is declared final. You probably won't want or need to declare your own classes final though.

final methods

You can also declare that methods are final. A method that is declared final cannot be overridden in a subclass. The syntax is simple, just put the keyword final after the access specifier and before the return type like this:

public final String convertCurrency()

final fields

You may also declare fields to be final. This is not the same thing as declaring a method or class to be final. When a field is declared final, it is a constant which will not and cannot change. It can be set once (for instance when the object is constructed, but it cannot be changed after that.) Attempts to change it will generate either a compile-time error or an exception (depending on how sneaky the attempt is).

Fields that are both final, static, and public are effectively named constants. For instance a physics program might define Physics.c, the speed of light as

public class Physics {

  public static final double c = 2.998E8;


}

In the SlowCar class, the speedLimit field is likely to be both final and static though it's private.

public class SlowCar extends Car {

  private final static double speedLimit = 112.65408; // kph == 70 mph

  public SlowCar(String licensePlate, double speed, double maxSpeed,
   String make, String model, int year, int numberOfPassengers, int numDoors) {
    super(licensePlate, 
     (speed < speedLimit) ? speed : speedLimit, 
     maxSpeed, make, model, year, numberOfPassengers, numDoors);
  }

  public void accelerate(double deltaV) {

     double speed = this.speed + deltaV;

     if (speed > this.maxSpeed) {
       speed = this.maxSpeed; 
     }

     if (speed > speedLimit) {
       speed = speedLimit;
     }

     if (speed < 0.0) {
       speed = 0.0; 
     } 

     this.speed = speed;    

  }

}

final arguments

Finally, you can declare that method arguments are final. This means that the method will not directly change them. Since all arguments are passed by value, this isn't absolutely required, but it's occasionally helpful.

等风也等你 2024-12-23 17:08:07

如果您知道某个东西永远不应该被重新分配,那么您就将其声明为最终的。您经常希望对方法参数执行此操作,因为重新分配方法参数几乎没有意义。

void foo(String str) { // no final
    str = "hijacked"; // perfectly fine
}

void foo(final String str) { // final
    str = "hijacked"; // compile error
}

C 和 C++ 使用 const 而不是 final,但我不能声称立即知道具体细节。

You declare something as final if you know that it should never be reassigned. You often want to do this to method parameters, since it rarely makes sense to reassign a method parameter.

void foo(String str) { // no final
    str = "hijacked"; // perfectly fine
}

void foo(final String str) { // final
    str = "hijacked"; // compile error
}

C and C++ use const instead of final, but I can't claim to know the specifics offhand.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文