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

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

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.

[quote=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.[/quote]

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?

[quote=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?[/quote]
Ah, é mesmo? Tem certeza?

Então por que nesse teste que eu fiz o compilador não acusou nenhum erro?[code]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{

}

}[/code]

[quote=ECO2004][quote=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.[/quote]

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?[/quote]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?

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

Correto :slight_smile: Seu próprio teste confirma isso

[quote=Hebert Coelho][quote=ECO2004][quote=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.[/quote]

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?[/quote]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?[/quote]

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]

[quote=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]

[/quote]
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.

[quote=ECO2004][quote=Hebert Coelho][quote=ECO2004][quote=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.[/quote]

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?[/quote]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?[/quote]

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]

[/quote]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.

[quote=Hebert Coelho][quote=ECO2004][quote=Hebert Coelho][quote=ECO2004][quote=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.[/quote]

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?[/quote]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?[/quote]

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]

[/quote]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.[/quote]

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.

[quote=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.[/quote]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. =/

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.

[quote=Hebert Coelho][quote=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.[/quote]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. =/[/quote]

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

[quote=ECO2004][quote=Hebert Coelho][quote=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.[/quote]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. =/[/quote]

Os livros do Use a Cabeça são bons, então? Vou dar uma olhada neles![/quote]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. [=

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.

[quote=ECO2004][quote=gomesrod]

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

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

[/quote]

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.[/quote]
Não gera erro porque não tem herança aí :slight_smile:

[quote=Hebert Coelho][quote=ECO2004][quote=Hebert Coelho][quote=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.[/quote]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. =/[/quote]

Os livros do Use a Cabeça são bons, então? Vou dar uma olhada neles![/quote]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. [=[/quote]

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

[quote=ECO2004]Você sabe se nesse livro menciona que um método sobrescrito somente não pode aumentar o número de exceções verificadas?[/quote]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. [=

[quote=Rodrigo Sasaki][quote=ECO2004][quote=gomesrod]

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

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

[/quote]

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.[/quote]
Não gera erro porque não tem herança aí :)[/quote]

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