7

Dado que ByteArrayOutputStream simplemente escribe en la memoria, nunca se debe producir un IOException. Sin embargo, debido al contrato de la interfaz OutputStream, todas las operaciones de flujo definen IOException en su cláusula throws.Java: IOException al escribir en ByteArrayOutputStream?

¿Cuál es la forma correcta de "manejar" este IOException que nunca se produce? Simplemente ajuste las operaciones en un bloque vacío try-catch?

¿O hay situaciones reales en las que ByteArrayOutputStream podría arrojar una excepción?

(Véase también: How can I handle an IOException which I know can never be thrown, in a safe and readable manner?)

EDITAR

Como Jon señala, ByteArrayOutputStream no declarar una cláusula throws en los write métodos que define - sin embargo, hereda write(byte[]) de OutputStream, y ese sí lanza IOEXception (es bastante extraño que BAOS no invalide este método, ya que podría reemplazar la versión de la superclase - que escribe un byte a la vez - con una llamada arraycopy mucho más eficiente)

Respuesta

9

Bueno, ByteArrayOutputStreamno declarar que cualquiera de sus métodos emiten IOException excepto writeTo y close. (No sé por qué close todavía lo declara, para ser honesto)

Sin embargo, si usted tiene una referencia del tipo OutputStream, aún verá las declaraciones de lanzamientos de eso, por supuesto.

No utilizaría un bloque catch vacío - Me tiraría algo así como IllegalStateException o una excepción no comprobada similares: significa que estás en una situación en la que realmente no espera, y algo ha ido muy mal.

+0

la IOException en 'close()' debe ser un error - especialmente cuando el javadoc dice que " no tiene efecto " – irreputable

+0

+1 ¡Gracias! Me acabo de dar cuenta de que 'ByteArrayOutputStream.write' en realidad no declara' IOException', pero Eclipse se queja de una excepción no controlada cada vez que la uso ... extraño. –

+0

@Jen: ¿Estás seguro de que estás llamando a métodos en una variable * declarada * como 'ByteArrayOutputStream'? –

1

Un cliché típico es throw new RuntimeException(theIOException) en el bloque catch. Si sucede lo imposible, al menos, averigüe sobre ello.

1

El encadenamiento de excepción es la mejor práctica en esta situación. es decir, lanzar una RuntimeException.

2

Me acabo de dar cuenta de que ByteArrayOutputStream.write en realidad no declara IOException, pero Eclipse se queja de una excepción no controlada cada vez que la uso ... extraño.

Eso es fácil de explicar. Es probable que haya hecho algo como esto:

OutputStream os = new ByteArrayOutputStream(); 
    ... 
    os.write(); 

El "problema" es que está llamando el método como OutputStream.write() más que como ByteArrayOutputStream.write(). Por lo que el compilador dice:

"Ah ... write() en una OutputStream puede lanzar una IOException, por lo que mucho tiene que con ella."

No puede decir:

"Este particular OutputStream es realmente un ByteArrayOutputStream ... por lo que le haremos fuera"

porque el JLS no permite.

Este es uno de esos casos extremos en los que la siguiente "práctica recomendada" al codificar la interfaz en lugar de la clase de implementación vuelve para morderte.

bien así ...

  • su una línea de contacto suave, no un bocado lleno-en.
  • OutputStream se implementa como una clase de Java, no una interfaz de Java, pero eso está al lado del punto.
  • mayoría de los compiladores en realidad no mantener conversaciones con usted al compilar el código :-)

+0

En general, tienes razón. Sin embargo, 'ByteArrayOutputStream' redefine ininteligentemente' close() 'sin hacer nada y lanza' IOException', por lo que en este caso el tipo de referencia no importa (OpenJDK). – musiKk

+0

Gracias, gran explicación. Descubrí lo que está pasando. Estoy llamando 'write (byte [])' desde dentro de una subclase de 'ByteArrayOutputStream'. 'BAOS' no anula este método, así que en realidad soy el método definido en' OutputStream' (que arroja un 'IOE') –

Cuestiones relacionadas