Qual é o equivalente da final do Java em C #?


560

Qual é o equivalente do Java finalem C #?


131
Um comentário no topo da aula dizendo "Se você substituir essa classe, será demitido!" (fora do curso a sua piada a :)
Hemant

Respostas:


861

A finalpalavra-chave tem vários usos em Java. Corresponde às palavras sealed- readonlychave e em C #, dependendo do contexto em que é usada.

Aulas

Para impedir a subclassificação (herança da classe definida):

Java

public final class MyFinalClass {...}

C #

public sealed class MyFinalClass {...}

Métodos

Impedir a substituição de um virtualmétodo.

Java

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

C #

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

Como Joachim Sauer aponta, uma diferença notável entre as duas linguagens aqui é que Java, por padrão, marca todos os métodos não estáticos como virtual, enquanto C # os marca como sealed. Portanto, você só precisa usar a sealedpalavra - chave em C # se desejar interromper a substituição de um método que foi explicitamente marcado virtualna classe base.

Variáveis

Para permitir que uma variável seja atribuída apenas uma vez:

Java

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

C #

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

Como observação lateral, o efeito da readonlypalavra - chave difere do efeito da palavra- constchave, pois a readonlyexpressão é avaliada em tempo de execução, em vez de em tempo de compilação , permitindo expressões arbitrárias.


15
Eu acrescentaria que todos os métodos não estáticos em Java são virtuais por padrão. Assim, enquanto no C #, você pode simplesmente deixar de fora o virtual na definição inicial, você vai precisar usar "final" para subclasses evitar a substituição-lo em Java
Joachim Sauer

167
boa resposta - existe mais um uso de "final" em java - em uma variável local ou parâmetro de método para impedir a sua reatribuição. Não há c # equivalente direto disso.
serg10

17
readonlyvariáveis ​​de membro podem ser modificadas em construtores: pastebin.com/AzqzYGiA
recursive

8
Observe também: se você declarar uma variável de membro como final em Java, o compilador reclamará, se nem todo construtor atribuir um valor em cada caminho de código, enquanto o C # emite apenas um aviso nesse cenário com variáveis ​​de membro somente leitura
Mene

1
@NickolayKondratyev: Sim, meu exemplo estava implícito em que você precisa estar subclassificando de outra classe. Você não precisa realmente da interface; isso é supérfluo, mas, do contrário, parece certo.
Noldorin

180

Depende do contexto.


1
Na verdade, não é necessário que uma variável final seja atribuída quando for declarada. 'final' significa que a variável deve ser atribuída por algum caminho de código antes de ser referenciada e nenhum caminho de código permite que a variável seja atribuída mais de uma vez. Isso se aplica a variáveis ​​de instância, o que significa que os construtores devem atribuir a variável explicitamente.
Jay

31
+ para For a final local variable or method parameter, there's no direct C# equivalentuma enorme distinção.
Daniel B. Chapman

1
Se você estiver instanciando , pode-se usar const para uma variável local. Não é equivalente, porque é claro última permite declarar separadamente e initialize (e por isso têm valores diferentes), mas apenas no caso de você não sabia ...
Griknok

3
constsó pode ser usado em tipos de valor. Tanto quanto sei, não há como fazer uma constante efetiva para um tipo de referência local.
jocull

2
@jocull Com cordas sendo a única exceção.
Raimund Krämer

46

O que todo mundo está perdendo é a garantia de Java de atribuição definitiva para variáveis ​​de membro final.

Para uma classe C com variável de membro final V, todo caminho de execução possível através de cada construtor de C deve atribuir V exatamente uma vez - deixar de atribuir V ou atribuir V duas ou mais vezes resultará em erro.

A palavra-chave readonly do C # não tem essa garantia - o compilador fica mais do que feliz em deixar os membros readonly não atribuídos ou permitir que você os atribua várias vezes em um construtor.

Portanto, final e somente leitura (pelo menos em relação às variáveis-membro) definitivamente não são equivalentes - final é muito mais rigoroso.


7

Como mencionado, sealedé equivalente finala métodos e classes.

Quanto ao resto, é complicado.

  • Para static finalcampos, static readonlyé a coisa mais próxima possível. Ele permite que você inicialize o campo estático em um construtor estático, que é bastante semelhante ao inicializador estático em Java. Isso se aplica a constantes (objetos primitivos e imutáveis) e a referências constantes a objetos mutáveis.

    O constmodificador é bastante semelhante para constantes, mas você não pode defini-las em um construtor estático.

  • Em um campo que não deve ser reatribuído depois que sai do construtor, readonlypode ser usado. Porém, não é igual - finalrequer exatamente uma atribuição, mesmo no construtor ou inicializador.
  • Não há C # equivalente para uma finalvariável local que eu conheça. Se você está se perguntando por que alguém precisaria dela: é possível declarar uma variável antes de um if-else, caso de mudança ou mais. Ao declarar final, você aplica que ele seja atribuído no máximo uma vez.

    As variáveis ​​locais Java em geral devem ser designadas pelo menos uma vez antes de serem lidas. A menos que o ramo salte antes da leitura do valor, uma variável final é atribuída exatamente uma vez. Tudo isso é verificado em tempo de compilação. Isso requer um código bem comportado com menos margem para um erro.

Resumindo, o C # não tem equivalente direto de final. Embora o Java não tenha alguns recursos interessantes do C #, é refrescante para mim, como programador Java, ver onde o C # falha em fornecer um equivalente.


6

Final da classe Java e método final -> selado. Variável de membro Java final -> somente leitura para constante de tempo de execução, const para constante de tempo de compilação.

Sem equivalente para variável local final e argumento de método final



0

selado


8
Que apenas parte da resposta, uma vez que depende do contexto e adicionando uma explicação e / ou exemplos irá torná-lo muito mais digerível para aqueles que precisam de ajuda
Rune FS
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.