Redefinição de método static e exceções

24 respostas
ECO2004

Quando eu “sobrescrevo” (override) um método em uma subclasse, esse método não pode listar mais exceções que o método da superclasse sobrescrito.
Quando falamos em métodos static, não há herança, mas sim redefinição.

Na redefinição abaixo, eu estou conseguindo listar mais exceções no método na subclasse que os presentes da superclasse. Nenhum erro é gerado. Quando eu mudo o conjunto de exceções da subclasse para apenas uma, Exception, um erro é gerado dizendo “Exception Exception is not compatible with throws clause in SuperclasseMetodoStatic.m()

public class SuperclasseMetodoStatic {
	
        public static void m() throws ArrayIndexOutOfBoundsException
        {
                 System.out.printf("%s", "Método m static na Superclasse");
        }
}

Subclasse sem geração de erro:

public class SubclasseMetodoStatic extends SuperclasseMetodoStatic{
	
        public static void n() throws ArithmeticException, ClassCastException
        {
              public static void m() throws Exception
              {
              }
        }
}

Subclasse com geração de erro:

public class SubclasseMetodoStatic extends SuperclasseMetodoStatic{
	
       public static void m() throws Exception
       {
              public static void m() throws Exception
              {
              }
        }
}

Eu não entendo do porquê da não geração de erro quando coloco mais exceções. No segundo caso, Exception é mais amplo que ArrayIndexOutOfBoundsException e por isso gera erro, presumo.

Alguém poderia me fazer o favor de explicar o que está acontecendo?

Wilson

24 Respostas

Rodrigo_Sasaki

Você está lançando exceções não-verificadas.

Vou reescrever sua frase:

Quando eu “sobrescrevo” (override) um método em uma subclasse, esse método não pode listar mais exceções verificadas que o método da superclasse sobrescrito.

Se você quiser colocar um throws pra uma exceção filha de RuntimeException, não terá problema nenhum.

ECO2004

Rodrigo Sasaki:
Você está lançando exceções não-verificadas.

Vou reescrever sua frase:

Quando eu “sobrescrevo” (override) um método em uma subclasse, esse método não pode listar mais exceções verificadas que o método da superclasse sobrescrito.

Se você quiser colocar um throws pra uma exceção filha de RuntimeException, não terá problema nenhum.

Não, Rodrigo. Eu não posso lançar nenhuma exceção além, não importa se é verificada ou não. Os livros dizem isso e testei.

Mais alguém poderia me ajudar, explicando o que está acontecendo?

Rodrigo_Sasaki
ECO2004:
Não, Rodrigo. Eu não posso lançar nenhuma exceção além, não importa se é verificada ou não. Os livros dizem isso e testei.

Mais alguém poderia me ajudar, explicando o que está acontecendo?


Ah, é mesmo? Tem certeza?

Então por que nesse teste que eu fiz o compilador não acusou nenhum erro?
public class Teste{

	public void metodo(){

	}

}

class SubTeste extends Teste{

	public void metodo() throws AnnotationTypeMismatchException, ArithmeticException, ArrayStoreException,
			BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException,
			ClassCastException, CMMException, ConcurrentModificationException, DataBindingException, DOMException,
			EmptyStackException, EnumConstantNotPresentException, EventException, IllegalArgumentException,
			IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException,
			IncompleteAnnotationException, IndexOutOfBoundsException, JMRuntimeException, LSException,
			MalformedParameterizedTypeException, MirroredTypeException, MirroredTypesException,
			MissingResourceException, NegativeArraySizeException, NoSuchElementException, NoSuchMechanismException,
			NullPointerException, ProfileDataException, ProviderException, RasterFormatException,
			RejectedExecutionException, SecurityException, SystemException, TypeConstraintException,
			TypeNotPresentException, UndeclaredThrowableException, UnknownAnnotationValueException,
			UnknownElementException, UnknownTypeException, UnmodifiableSetException, UnsupportedOperationException,
			WebServiceException{

	}
}
Hebert_Coelho

ECO2004:
Rodrigo Sasaki:
Você está lançando exceções não-verificadas.

Vou reescrever sua frase:

Quando eu “sobrescrevo” (override) um método em uma subclasse, esse método não pode listar mais exceções verificadas que o método da superclasse sobrescrito.

Se você quiser colocar um throws pra uma exceção filha de RuntimeException, não terá problema nenhum.

Não, Rodrigo. Eu não posso lançar nenhuma exceção além, não importa se é verificada ou não. Os livros dizem isso e testei.

Mais alguém poderia me ajudar, explicando o que está acontecendo?

Sério? :shock: :shock: :shock: :shock: :shock: :shock: :shock:

Vou jogar minha certificação no lixo e começar a ler tudo de novo… deve ser Java 7…

Qual foi o livro por gentileza?

ECO2004

Rodrigo, você está certo. Eu testei certo, mas disse errado. Eu olhei de maneira trocada as minhas classes.
Mas o livro realmente não fala em ser verificada.

Agora, com relação a minha dúvida: não havendo herança e sim redefinição (o método é static), as regras de exceções ainda valem, né? O método redefinido na subclasse não pode lançar mais exceções verificadas que o método na superclasse, correto?

Wilson

Rodrigo_Sasaki

Correto :slight_smile: Seu próprio teste confirma isso

ECO2004

Hebert Coelho:
ECO2004:
Rodrigo Sasaki:
Você está lançando exceções não-verificadas.

Vou reescrever sua frase:

Quando eu “sobrescrevo” (override) um método em uma subclasse, esse método não pode listar mais exceções verificadas que o método da superclasse sobrescrito.

Se você quiser colocar um throws pra uma exceção filha de RuntimeException, não terá problema nenhum.

Não, Rodrigo. Eu não posso lançar nenhuma exceção além, não importa se é verificada ou não. Os livros dizem isso e testei.

Mais alguém poderia me ajudar, explicando o que está acontecendo?

Sério? :shock: :shock: :shock: :shock: :shock: :shock: :shock:

Vou jogar minha certificação no lixo e começar a ler tudo de novo… deve ser Java 7…

Qual foi o livro por gentileza?

Deitel. Diz apenas sobre exceções, sem especificar que tem que ser verificadas.

If a subclass method overrides a superclass method, it’s an error for the subclass method to
list more exceptions in its throws clause than the overridden superclass method does. However,
a subclass’s throws clause can contain a subset of a superclass’s throws list.
- Deitel, 9º edição [inclui Java 7]

Rodrigo_Sasaki

ECO2004:
If a subclass method overrides a superclass method, it’s an error for the subclass method to
list more exceptions in its throws clause than the overridden superclass method does. However,
a subclass’s throws clause can contain a subset of a superclass’s throws list.
- Deitel, 9º edição [inclui Java 7]


Nossa, realmente. É um detalhe que vale a pena ser mencionado.

Talvez não tenham mencionado porque não é comum um método declarar que lança uma RuntimeException, mas mesmo assim, acho que eles pisaram na bola.

Hebert_Coelho

ECO2004:
Hebert Coelho:
ECO2004:
Rodrigo Sasaki:
Você está lançando exceções não-verificadas.

Vou reescrever sua frase:

Quando eu “sobrescrevo” (override) um método em uma subclasse, esse método não pode listar mais exceções verificadas que o método da superclasse sobrescrito.

Se você quiser colocar um throws pra uma exceção filha de RuntimeException, não terá problema nenhum.

Não, Rodrigo. Eu não posso lançar nenhuma exceção além, não importa se é verificada ou não. Os livros dizem isso e testei.

Mais alguém poderia me ajudar, explicando o que está acontecendo?

Sério? :shock: :shock: :shock: :shock: :shock: :shock: :shock:

Vou jogar minha certificação no lixo e começar a ler tudo de novo… deve ser Java 7…

Qual foi o livro por gentileza?

Deitel. Diz apenas sobre exceções, sem especificar que tem que ser verificadas.

If a subclass method overrides a superclass method, it’s an error for the subclass method to
list more exceptions in its throws clause than the overridden superclass method does. However,
a subclass’s throws clause can contain a subset of a superclass’s throws list.
- Deitel, 9º edição [inclui Java 7]

Beleza… Como ele não fala qual o tipo de exception a gente também não pode afirmar, né?

Mas pelo menos você tirou sua dúvida.

ECO2004

Hebert Coelho:
ECO2004:
Hebert Coelho:
ECO2004:
Rodrigo Sasaki:
Você está lançando exceções não-verificadas.

Vou reescrever sua frase:

Quando eu “sobrescrevo” (override) um método em uma subclasse, esse método não pode listar mais exceções verificadas que o método da superclasse sobrescrito.

Se você quiser colocar um throws pra uma exceção filha de RuntimeException, não terá problema nenhum.

Não, Rodrigo. Eu não posso lançar nenhuma exceção além, não importa se é verificada ou não. Os livros dizem isso e testei.

Mais alguém poderia me ajudar, explicando o que está acontecendo?

Sério? :shock: :shock: :shock: :shock: :shock: :shock: :shock:

Vou jogar minha certificação no lixo e começar a ler tudo de novo… deve ser Java 7…

Qual foi o livro por gentileza?

Deitel. Diz apenas sobre exceções, sem especificar que tem que ser verificadas.

If a subclass method overrides a superclass method, it’s an error for the subclass method to
list more exceptions in its throws clause than the overridden superclass method does. However,
a subclass’s throws clause can contain a subset of a superclass’s throws list.
- Deitel, 9º edição [inclui Java 7]

Beleza… Como ele não fala qual o tipo de exception a gente também não pode afirmar, né?

Mas pelo menos você tirou sua dúvida.

Então, na prática eu posso aumentar o número de exceções no método que estou sobrescrevendo, mas o livro não explicita isso. Detalhe que ele contém as novidades do Java 7.

Hebert_Coelho

ECO2004:
Então, na prática eu posso aumentar o número de exceções no método que estou sobrescrevendo, mas o livro não explicita isso. Detalhe que ele contém as novidades do Java 7.
Na boa mano?
Larga esse livro. [=
Vai pra um Use a Cabeça da vida, ou então o da certificação da Katty Cierra (sei lá como se escreve o nome dela).

Sempre vi diversas pessoas criticando esse livro q vc ta lendo. Triste viu. =/

gomesrod

Nesse caso não deveria, pois o método redefinido é outro, não tem relação com o da superclasse.
Aqui um exemplo:

class Base {
	static void m() throws IOException {
		
	}
}

class Derived {
        // Compila normalmente
	static void m() throws Exception {
		
	}
}

Agora… é coisa da minha cabeça ou isso aqui tá esquisito?

public class SubclasseMetodoStatic extends SuperclasseMetodoStatic{  
          
            public static void n() throws ArithmeticException, ClassCastException  
            {  
                  public static void m() throws Exception  
                  {  
                  }  
            }  
    }  
    public class SubclasseMetodoStatic extends SuperclasseMetodoStatic{  
          
           public static void m() throws Exception  
           {  
                  public static void m() throws Exception  
                  {  
                  }  
            }  
    }

E sobre as exceções não checadas, coloca-las na cláusula throws não interfere em nada na compilação nem na execução, é só para documentar mesmo. Por isso que o livro nem se preocupou em citar o caso.

ECO2004

Hebert Coelho:
ECO2004:
Então, na prática eu posso aumentar o número de exceções no método que estou sobrescrevendo, mas o livro não explicita isso. Detalhe que ele contém as novidades do Java 7.
Na boa mano?
Larga esse livro. [=
Vai pra um Use a Cabeça da vida, ou então o da certificação da Katty Cierra (sei lá como se escreve o nome dela).

Sempre vi diversas pessoas criticando esse livro q vc ta lendo. Triste viu. =/

Os livros do Use a Cabeça são bons, então? Vou dar uma olhada neles!

Hebert_Coelho

ECO2004:
Hebert Coelho:
ECO2004:
Então, na prática eu posso aumentar o número de exceções no método que estou sobrescrevendo, mas o livro não explicita isso. Detalhe que ele contém as novidades do Java 7.
Na boa mano?
Larga esse livro. [=
Vai pra um Use a Cabeça da vida, ou então o da certificação da Katty Cierra (sei lá como se escreve o nome dela).

Sempre vi diversas pessoas criticando esse livro q vc ta lendo. Triste viu. =/

Os livros do Use a Cabeça são bons, então? Vou dar uma olhada neles!

na moral? por mim, eu leria todos. Olha só os que eu já li:
Head First Design Patterns ? Elisabeth Freeman
Head First HTML and CSS ? Elisabeth Robson, Eric Freeman
Head First Java ? Kathy Sierra
Head First Object-Oriented Analysis & Design ? Brett D. McLaughlin
Head First Servlet & JSP ? Bryan Basham

E na boa? Os códigos funcionam numa boa… Explicam devagar e muito bom viu. [=

ECO2004

O seu código gera erro. Exception Exception is not compatible with throws clause in Base
Isso ocorre porque Exception é a superclasse de IOException. Assim, você aumentou a quantidade de exceções que podem ser lançadas na subclasse, incluindo as verificadas.
O erro gerado é igual ao meu anterior.

Rodrigo_Sasaki

ECO2004:
gomesrod:

class Base {
	static void m() throws IOException {
		
	}
}

class Derived {
        // Compila normalmente
	static void m() throws Exception {
		
	}
}

O seu código gera erro. Exception Exception is not compatible with throws clause in Base
Isso ocorre porque Exception é a superclasse de IOException. Assim, você aumentou a quantidade de exceções que podem ser lançadas na subclasse, incluindo as verificadas.
O erro gerado é igual ao meu anterior.


Não gera erro porque não tem herança aí :slight_smile:

ECO2004

Hebert Coelho:
ECO2004:
Hebert Coelho:
ECO2004:
Então, na prática eu posso aumentar o número de exceções no método que estou sobrescrevendo, mas o livro não explicita isso. Detalhe que ele contém as novidades do Java 7.
Na boa mano?
Larga esse livro. [=
Vai pra um Use a Cabeça da vida, ou então o da certificação da Katty Cierra (sei lá como se escreve o nome dela).

Sempre vi diversas pessoas criticando esse livro q vc ta lendo. Triste viu. =/

Os livros do Use a Cabeça são bons, então? Vou dar uma olhada neles!

na moral? por mim, eu leria todos. Olha só os que eu já li:
Head First Design Patterns ? Elisabeth Freeman
Head First HTML and CSS ? Elisabeth Robson, Eric Freeman
Head First Java ? Kathy Sierra
Head First Object-Oriented Analysis & Design ? Brett D. McLaughlin
Head First Servlet & JSP ? Bryan Basham

E na boa? Os códigos funcionam numa boa… Explicam devagar e muito bom viu. [=

Você sabe se nesse livro menciona que um método sobrescrito somente não pode aumentar o número de exceções verificadas?

Hebert_Coelho

ECO2004:
Você sabe se nesse livro menciona que um método sobrescrito somente não pode aumentar o número de exceções verificadas?
Sabe não. [=

Mano, eu li esse livro de Java a muuuuuito tempo atrás… =/

Agora o da Kathy Sierra sobre certificação eu tenho certeza que fala. [=

ECO2004

Rodrigo Sasaki:
ECO2004:
gomesrod:

class Base {
	static void m() throws IOException {
		
	}
}

class Derived {
        // Compila normalmente
	static void m() throws Exception {
		
	}
}

O seu código gera erro. Exception Exception is not compatible with throws clause in Base
Isso ocorre porque Exception é a superclasse de IOException. Assim, você aumentou a quantidade de exceções que podem ser lançadas na subclasse, incluindo as verificadas.
O erro gerado é igual ao meu anterior.


Não gera erro porque não tem herança aí :)

Não tem…eu que coloquei extends no meu. :slight_smile:

ECO2004

Hebert Coelho:
ECO2004:
Você sabe se nesse livro menciona que um método sobrescrito somente não pode aumentar o número de exceções verificadas?
Sabe não. [=

Mano, eu li esse livro de Java a muuuuuito tempo atrás… =/

Agora o da Kathy Sierra sobre certificação eu tenho certeza que fala. [=

Valeu!!

gomesrod

Rodrigo Sasaki:

Não gera erro porque não tem herança aí :)

Não fique se prendendo a esses detalhes insignificantes :slight_smile:

Retiro o que eu disse sobre não dar erro, mas continuo achando que no caso dos métodos estáticos isso não faz sentido!
Para os métodos normais (não static) essa regra existe porque o método sobrescrito precisa respeitar o contrato definido pela classe mãe, por causa do polimorfismo.
Mas os estáticos são totalmente independentes. Não dá para chamar o método da classe filha por uma referência da classe mãe.

Até que alguém me explique vou considerar isso um defeito do Java ! :shock:

ECO2004

gomesrod:
Rodrigo Sasaki:

Não gera erro porque não tem herança aí :)

Não fique se prendendo a esses detalhes insignificantes :slight_smile:

Retiro o que eu disse sobre não dar erro, mas continuo achando que no caso dos métodos estáticos isso não faz sentido!
Para os métodos normais (não static) essa regra existe porque o método sobrescrito precisa respeitar o contrato definido pela classe mãe, por causa do polimorfismo.
Mas os estáticos são totalmente independentes. Não dá para chamar o método da classe filha por uma referência da classe mãe.

Até que alguém me explique vou considerar isso um defeito do Java ! :shock:

Não tem sentido chamar um método static através de um objeto, já que o método pertence à classe. Assim, em uma chamada polimórfica, o Java ignora o objeto e se restringe apenas ao tipo de variável declarada para chamar o método. Por isso, somente é chamado o método static da superclasse através de polimorfismo.

ECO2004

Os livros Core Java são bons para certificação?

gomesrod

Exatamente !
É justamente por isso que não existe sentido em obrigar o método estático da classe filha a respeitar o contrato daquele outro método na classe mãe.

Criado 31 de janeiro de 2013
Ultima resposta 31 de jan. de 2013
Respostas 24
Participantes 4