Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

162
Visualizações
Escriba el procedimiento de resolución de inferencia que involucra la cláusula throws en Java

Considere el siguiente artículo en JLS §18.1.3 - Límites

Aquí, cuando tratamos de identificar el conjunto de límites en las variables de inferencia, tenemos una de las siguientes situaciones:

...

  • throws α: La variable de inferencia α aparece en una cláusula throws.

...

Un límite de la forma throws α es puramente informativo: dirige la resolución para optimizar la creación de instancias de α para que, si es posible, no sea un tipo de excepción comprobada .

Creo que esta afirmación es incorrecta:

  • esto se debe a que, idealmente, la cláusula throws se menciona para ocuparse de las excepciones verificadas que pueden ocurrir durante el curso de la ejecución del código.
  • Entonces, ¿por qué el JLS sigue impidiendo que α sea una excepción comprobada?
  • Idealmente, la variable de inferencia α debe estar limitada para ser una excepción del tipo Checked en lugar de ser una variante Unchecked .

¿Es correcto mi entendimiento aquí o me estoy perdiendo algo?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Creo que su interpretación/comprensión de esta declaración es un poco equivocada:

Un límite de la forma throws α es puramente informativo: dirige la resolución para optimizar la creación de instancias de α para que, si es posible, no sea un tipo de excepción comprobada.

Esa línea se refiere a la resolución, que, según tengo entendido, no se trata de dónde throws α , sino de dónde se infiere α , posiblemente la invocación del método.

Considere esta clase:

 static class MyClass { public static void main(String[] args) { MyClass.<RuntimeException>something(0); // same as MyClass.something(1); try { MyClass.<IOException>something(2); } catch (IOException ex) { // checked exception } } /** * Will throw IOException if argument is 2, a RuntimeException otherwise */ static <T extends Exception> void something(int a) throws T { if (a == 2) { throw (T) new IOException(); //of course it's a bad cast } else { throw (T) new Exception(); } } }

Después de analizar el método de dos something , concéntrese en la invocación en el método main :

La llamada MyClass.<IOException>something(0) espera una IOException. La persona que llama lo sabe (suponga un contrato completamente documentado en lugar de un código estrechamente acoplado) y maneja la excepción.
Esto ya te dice que la variable puede ser una excepción comprobada, al contrario de lo que piensas.

Por el contrario, la llamada MyClass.<RuntimeException>something(0) espera una excepción de tiempo de ejecución por motivos similares.

La forma en que se infiere α ( T en el ejemplo anterior) permite que el compilador omita obligar a la persona que llama a capturar/manejar la excepción (si es para ver el límite, que de otro modo tendría que hacerlo)

Ahora sobre la "optimización": se puede esperar razonablemente que la variable de tipo que se limita a medida que extends Exception se resuelva en una excepción marcada. Pero, si la persona que llama sabe que será una excepción de tiempo de ejecución, puede "informar" al compilador que será una excepción de tiempo de ejecución. Esto es lo que hice al especificar RuntimeException en el testigo de tipo ( RuntimeException también es el tipo resuelto cuando no se proporciona explícitamente ningún argumento de tipo).

Podemos pasar días para interpretar la "optimización", pero al menos yo, como llamador, no tuve que intentar/atrapar la invocación, y aún así no molesté al compilador (primera invocación).

over 4 years ago · Santiago Trujillo Relatório

0

Considere este ejemplo:

 public class Main { public static void main(String[] args) { foo(() -> System.out.println("Foo")); } public static <T extends Exception> void foo(ThrowingRunnable<T> runnable) throws T { runnable.run(); } } interface ThrowingRunnable<T extends Exception> { void run() throws T; }

Durante la inferencia del parámetro de tipo T al llamar a foo , habrá un límite de "lanzamientos" en la variable de tipo T , y se infiere que T es RuntimeException . Si no fuera por este límite, T se habría inferido como Exception debido a que T extends Exception . Esto habría significado que necesitaba hacer:

 try { foo(() -> System.out.println("Foo")); catch (Exception e) { // This won't be reached! }

¡Tuve que manejar la excepción, aunque todo lo que hago en la lambda es imprimir cosas! Eso no parece muy agradable, ¿verdad?

El propósito de este límite es que si no hay razón para que el método arroje una excepción verificada, no arroje una excepción verificada, de modo que no tenga que escribir tantos intentos... capturas por todas partes. . foo solo arrojaría una excepción comprobada si hace cosas como:

 foo(() -> new FileOutputStream("foo"));

Si el efecto del límite fuera forzar a T a ser una excepción comprobada, no sería muy útil.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda