Por que todos os campos em uma interface são implicitamente estáticos e finais?

100

Estou apenas tentando entender por que todos os campos definidos em uma Interface são implicitamente statice final. A ideia de manter campos staticfaz sentido para mim, já que você não pode ter objetos de uma interface, mas por que eles existem final(implicitamente)?

Alguém sabe por que os designers de Java criaram os campos em uma interface statice final?

picoit
fonte
Para uma nota para mim: é estático porque os campos da interface não se tornarão parte do objeto que o implementa.
Chovendo em

Respostas:

126

Uma interface não pode ter comportamento ou estado porque se destina a especificar apenas um contrato de interação, sem detalhes de implementação. 'Nenhum comportamento' é imposto ao não permitir corpos de método / construtor ou blocos de inicialização estática / instância. 'Nenhum estado' é imposto permitindo apenas campos finais estáticos. Portanto, a classe pode ter um estado (estado estático), mas o estado da instância não é inferido pela interface.

BTW: uma constante em Java é definida por um campo final estático (e por convenção o nome usa UPPER_CASE_AND_UNDERSCORES).

Adriaan Koster
fonte
54
Não é necessariamente verdade que os campos finais são constantes; isso é garantido apenas para tipos primitivos. Em geral, a palavra-chave final significa apenas que a localização da memória não mudará.
Aparece em
8
Eu não disse que os campos finais são constantes, apenas que as constantes são campos finais. Observe que é permitido colocar um campo final estático não primitivo em uma interface. Mesmo que o conteúdo desse campo possa mudar, a referência a ele é constante.
Adriaan Koster
1
@AdriaanKoster Você disse exatamente que o campo final é constante: nenhum estado é imposto permitindo apenas constantes. - esta frase implica que todos os campos finais são constantes. Você pode tentar argumentar mais sobre as palavras que usou, mas obviamente sua afirmação é, pelo menos, enganosa.
Tomáš Zato - Reintegração de Monica,
2
Deve ser meu intelecto enfraquecido, mas depois de seis anos olhando para esta resposta, que por acaso é minha resposta de maior pontuação, ainda não entendo as observações. Sugira um texto diferente porque não consigo ver nada de errado.
Adriaan Koster,
Pode ter sido a intenção dos designers de java tornar uma interface sem estado, mas eles falharam porque um campo de instância pode ser uma classe modificável. Em vez de admitir que falharam, eles optam por forçar os campos de instância a static final, o que é o mais próximo do real (sendo o real C / C ++) constque você pode obter em java. Infelizmente, isso está implícito e pode causar confusão para quem não é especialista. (Acabei de perceber que são staticporque observei um comportamento não intencional. Aprendi que são finalapenas a partir desta resposta.)
não um usuário
27

Razão de ser final

Qualquer implementação pode alterar o valor dos campos se eles não forem definidos como finais. Então, eles se tornariam parte da implementação. Uma interface é uma especificação pura sem qualquer implementação.

Razão de ser static

Se eles forem estáticos, eles pertencem à interface e não ao objeto, nem ao tipo de tempo de execução do objeto.

Gurpreet singh sidhuu
fonte
18

Existem alguns pontos atenuados aqui:

Só porque os campos em uma interface são implicitamente estáticos final não significa que eles devem ser constantes de tempo de compilação, ou mesmo imutáveis. Você pode definir, por exemplo

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(Esteja ciente de que fazer isso dentro de uma definição de anotação pode confundir javac , relacionado ao fato de que o acima realmente compila para um inicializador estático.)

Além disso, a razão para essa restrição é mais estilística do que técnica, e muitas pessoas gostariam de ver isso relaxado .

Jesse Glick
fonte
9

Os campos devem ser estáticos porque não podem ser abstratos (como os métodos podem). Como eles não podem ser abstratos, os implementadores não serão capazes de fornecer logicamente as diferentes implementações dos campos.

Os campos devem ser finais, eu acho, porque os campos podem ser acessados ​​por muitos implementadores diferentes, permite que eles sejam alteráveis ​​pode ser problemático (como sincronização). Também para evitar que seja reimplementado (escondido).

Apenas meu pensamento.

NawaMan
fonte
NawMan, sua explicação sobre "Os campos devem ser estáticos ..." não faz muito sentido. Mas você estava certo sobre "Os campos devem ser finais ..."
pico de
1
Não acho que ele esteja certo sobre o motivo pelo qual os campos devem ser finais. Permitir que diferentes implementadores alterem um campo não é problemático, pois do contrário, a herança seria problemática. Os campos devem ser finais, como disse Adriaan, porque uma interface é, e deve, ser sem estado. Uma interface com um estado basicamente deve ser uma classe abstrata.
Axelle Ziegler,
Se você tiver um public staticcampo que não seja final, o findbugs reclamará (com razão!).
Tom Hawtin - tackline,
2

Considero a exigência de que os campos sejam finais como excessivamente restritivos e um erro dos designers da linguagem Java. Há momentos, por exemplo, manuseio de árvore, quando você precisa definir constantes na implementação que são necessárias para realizar operações em um objeto do tipo de interface. Selecionar um caminho de código na classe de implementação é uma confusão. A solução alternativa que uso é definir uma função de interface e implementá-la retornando um literal:

public interface iMine {
    String __ImplementationConstant();
    ...
}

public class AClass implements iMine {
    public String __ImplementationConstant(){
        return "AClass value for the Implementation Constant";
    }
    ...
}

public class BClass implements iMine {
    public String __ImplementationConstant(){
        return "BClass value for the Implementation Constant";
    }
    ...
}

No entanto, seria mais simples, mais claro e menos sujeito a uma implementação aberrante usar esta sintaxe:

public interface iMine {
    String __ImplementationConstant;
    ...
}

public class AClass implements iMine {
    public static String __ImplementationConstant =
        "AClass value for the Implementation Constant";
    ...
}

public class BClass implements iMine {
    public static String __ImplementationConstant =
        "BClass value for the Implementation Constant";
    ...
}
Carl Klapper
fonte
Você parece estar reclamando mais sobre os campos serem estáticos do que finais.
Daniel Yankowsky
0

Especificação, contratos ... A instrução da máquina para acesso ao campo usa o endereço do objeto mais o deslocamento do campo. Como as classes podem implementar muitas interfaces, não há como fazer com que o campo de interface não final tenha o mesmo deslocamento em todas as classes que estendem essa interface. Portanto, um mecanismo diferente para o acesso ao campo deve ser implementado: dois acessos à memória (obter o deslocamento do campo, obter o valor do campo) em vez de um, além de manter o tipo de tabela de campo virtual (analógico da tabela de método virtual). Acho que eles simplesmente não queriam complicar o jvm para a funcionalidade que pode ser facilmente simulada por meio de coisas existentes (métodos).

No scala, podemos ter campos nas interfaces, embora internamente eles sejam implementados conforme expliquei acima (como métodos).

Yaroslav
fonte
-1

static:

Qualquer coisa (variável ou método) que esteja staticem Java pode ser invocado como Classname.variablenameou Classname.methodnameou diretamente. Não é obrigatório invocá-lo apenas usando o nome do objeto.

Na interface, os objetos não podem ser declarados e staticpossibilita invocar variáveis ​​apenas através do nome da classe sem a necessidade do nome do objeto.

final:

Isso ajuda a manter um valor constante para uma variável, pois não pode ser sobrescrito em suas subclasses.

Sabika
fonte