¿Cuál es el equivalente de la final de Java en C #?

560

¿Cuál es el equivalente de Java finalen C #?

Nosrama
fuente
131
Un comentario en la parte superior de la clase que dice "Si anula esta clase, ¡está despedido!" (Por supuesto, es una broma :)
Hemant

Respuestas:

861

La finalpalabra clave tiene varios usos en Java. Se corresponde con las palabras clave sealedy readonlyen C #, según el contexto en el que se utiliza.

Clases

Para evitar subclases (herencia de la clase definida):

Java

public final class MyFinalClass {...}

C#

public sealed class MyFinalClass {...}

Métodos

Prevenir la anulación de un virtualmétodo.

Java

public class MyClass
{
    public final void myFinalMethod() {...}
}

C#

public class MyClass : MyBaseClass
{
    public sealed override void MyFinalMethod() {...}
}

Como señala Joachim Sauer, una diferencia notable entre los dos lenguajes aquí es que Java marca por defecto todos los métodos no estáticos como virtual, mientras que C # los marca como sealed. Por lo tanto, solo necesita usar la sealedpalabra clave en C # si desea detener la anulación adicional de un método que se ha marcado explícitamente virtualen la clase base.

Variables

Para permitir que solo se asigne una variable una vez:

Java

public final double pi = 3.14; // essentially a constant

C#

public readonly double pi = 3.14; // essentially a constant

Como nota al margen, el efecto de la readonlypalabra clave difiere del de la constpalabra clave en que la readonlyexpresión se evalúa en tiempo de ejecución en lugar de tiempo de compilación , por lo que permite expresiones arbitrarias.

Noldorin
fuente
15
Añadiría que todos los métodos no estáticos en Java son virtuales por defecto. Así, mientras que en C # puede simplemente dejar de lado el virtual en la definición inicial, tendrá que utilizar "final" a las subclases Evita anulando en Java
Joachim Sauer
167
buena respuesta, aunque hay un uso más de "final" en java, en una variable local o parámetro de método para evitar reasignarlo. No hay un equivalente directo de c # de esto.
serg10
17
readonlylas variables miembro se pueden modificar en los constructores: pastebin.com/AzqzYGiA
recursivo el
8
También tenga en cuenta: si declara una variable miembro como final en Java, el compilador se quejará, si no todos los constructores asignan un valor en cada ruta de código, mientras que C # solo emite una advertencia en ese escenario con variables de miembro de solo lectura
Mene
1
@NickolayKondratyev: Sí, mi ejemplo estaba implícito en que debes estar subclasificando de otra clase. Realmente no necesitas la interfaz; eso es superfluo, pero por lo demás eso parece correcto.
Noldorin
180

Depende del contexto.

LukeH
fuente
1
En realidad, no se requiere que se asigne una variable final cuando se declara. 'final' significa que la variable debe ser asignada por alguna ruta de código antes de hacer referencia a ella y que ninguna ruta de código permite asignar la variable más de una vez. Esto se aplica a las variables de instancia, lo que en efecto significa que los constructores deben asignar la variable explícitamente.
Jay
31
+ para For a final local variable or method parameter, there's no direct C# equivalentuna gran distinción.
Daniel B. Chapman
1
Si está creando instancias , se puede usar const para una variable local. No es equivalente porque, por supuesto, final le permite declarar e inicializar por separado (y así tener valores diferentes), pero en caso de que no lo supiera ...
Griknok
3
constsolo se puede usar en tipos de valor. Hasta donde sé, no hay forma de hacer una constante efectiva para un tipo de referencia local.
jocull
2
@jocull Las cadenas son la única excepción.
Raimund Krämer
46

Lo que falta a todos aquí es la garantía de Java de asignación definitiva para las variables miembro finales.

Para una clase C con la variable de miembro final V, cada ruta de ejecución posible a través de cada constructor de C debe asignar V exactamente una vez: no asignar V o asignar V dos o más veces dará como resultado un error.

La palabra clave de solo lectura de C # no tiene esa garantía: el compilador está más que feliz de dejar miembros de solo lectura sin asignar o permitirle asignarlos varias veces dentro de un constructor.

Entonces, final y readonly (al menos con respecto a las variables miembro) definitivamente no son equivalentes: final es mucho más estricto.

Algún chico
fuente
7

Como se mencionó, sealedes un equivalente de finalpara métodos y clases.

En cuanto al resto, es complicado.

  • Para los static finalcampos, static readonlyes lo más cercano posible. Le permite inicializar el campo estático en un constructor estático, que es bastante similar al inicializador estático en Java. Esto se aplica tanto a las constantes (primitivas y objetos inmutables) como a las referencias constantes a objetos mutables.

    El constmodificador es bastante similar para las constantes, pero no puede configurarlas en un constructor estático.

  • En un campo que no debe reasignarse una vez que abandona el constructor, readonlyse puede utilizar. Sin embargo, no es igual: finalrequiere exactamente una asignación incluso en constructor o inicializador.
  • No hay un equivalente de C # para una finalvariable local que yo sepa. Si se pregunta por qué alguien lo necesitaría: puede declarar una variable antes de un if-else, switch-case o algo así. Al declararlo final, usted impone que se asigne como máximo una vez.

    Las variables locales de Java en general deben asignarse al menos una vez antes de leerse. A menos que la rama salte antes de leer el valor, se asigna una variable final exactamente una vez. Todo esto se verifica en tiempo de compilación. Esto requiere un código de buen comportamiento con menos margen para un error.

En resumen, C # no tiene un equivalente directo de final. Si bien Java carece de algunas características agradables de C #, es refrescante para mí, principalmente como programador de Java, ver dónde C # no puede ofrecer un equivalente.

Vlasec
fuente
6

Clase de Java final y método final -> sellado. Variable miembro Java final -> solo lectura para constante de tiempo de ejecución, constante para constante de tiempo de compilación.

No hay equivalente para la Variable local final y el argumento del método final

Vijayakumarpl
fuente
0

sellado

x2.
fuente
8
Que sólo parte de la respuesta, ya que depende del contexto y la adición de una explicación y / o ejemplos hará que sea mucho más digerible para los necesitados de ayuda
runa FS