20250225 Exception1 - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
Vale, entonces, si habláis, me autorizáis a grabar vuestras voces.
00:00:01
Vamos a ver un poquito rápidamente qué es el manejo de excepciones en Java.
00:00:06
Es decir, cuando surgen algún tipo de errores a tiempo de ejecución en Java,
00:00:13
¿qué puedo hacer para intentar evitar que mi programa deje de funcionar y en un cierto sentido se recupere?
00:00:19
La idea del manejo de excepciones es que errores pueden surgir y hay un mogollón de errores posibles, pero hasta ahora nosotros frente a cualquier tipo de error mi programa se acababa, pero quiero intentar evitar que esto pase.
00:00:27
A los usuarios no les gusta que mi programa se bloquee o se apague solo o que se destruya.
00:00:45
Como mínimo, si se tiene que destruir porque no puede seguir adelante, ha sido un error crítico, pues que al menos me diga algo.
00:00:52
Me diga, oye, mira, lo que has hecho está muy mal. Cuanto más detallado puedo ser, mejor.
00:01:00
Luego depende también del tipo de manejo de errores para quien lo hago.
00:01:07
Si estoy intentando hablar al usuario y hacerle entender algo o si son más bien mensajes técnicos derivantes a quien haga el mantenimiento técnico de esos programas y esos códigos, que sepa que este código es una determinada cosa, a mí me viene un código raro, yo usuario no lo entiendo, pero el desarrollador sí que podrá entenderlo, ¿vale?
00:01:13
El concepto es que una excepción es un error
00:01:37
Un fallo del programa que ocurre en tiempo de ejecución
00:01:41
A tiempo de compilación nosotros hacemos errores constantemente
00:01:44
No ponemos un punto y coma
00:01:48
Usamos un método que no existe
00:01:50
Extendemos una clase strata
00:01:52
Y no hemos implementado todos los métodos de la clase strata
00:01:55
Estos son errores que se pueden sacar a tiempo de compilación
00:02:00
O sea, antes de ejecutar el programa
00:02:04
ya el compilador o el entorno de desarrollo puede hacerme una revisión de lo que he escrito
00:02:06
y decirme, mira, aquí hay un problema.
00:02:16
Típico también meter un double dentro de variable int.
00:02:18
Él sabe que aquí hay una caja para int, tú estás poniendo un valor que es un double,
00:02:23
lo puede detectar antes de ejecutar el programa.
00:02:29
Otros errores en vez no se pueden detectar.
00:02:32
Cuando yo le digo scan.nextint diciendo que voy a leer un número, no puedo saber a tiempo de compilación que el usuario malvado en vez de un número pondrá gato.
00:02:36
Entonces, allí no puedo hacer nada a nivel de compilador de decir, oye, mira que aquí hay un error.
00:02:48
Porque el error podría no haberlo.
00:02:55
Será solo en el momento en que ejecuto que este error se podría manifestar.
00:02:57
Estos errores que se manifiestan a tiempo de ejecución son las excepciones.
00:03:03
Cuando un error ocurre, lo más normal es que se detenga el programa y se proporcione un mensaje de explique el fallo.
00:03:09
Vosotros estaréis acostumbrados cuando hay un null pointer exception, cuando hay un index out of bound exception,
00:03:15
vuestro programa se acaba, sale un listado de cosas en rojo y allí se acabó.
00:03:21
Es lo que estamos haciendo hasta ahora. Ese listado de cosas en rojo que salen es un system.out.println. Vuestro programa tiene tres canales de comunicación siempre.
00:03:31
Un input, system.in, que nosotros lo hemos visto en scanner, se lo pasamos como parámetro al scanner. Un system.out, que es el que escribe en consola, que es el que usamos nosotros ahora para decir cosas al usuario. Y luego está un system.er, que es igual a un system.out, pero está pensado para que tú escribas mensajes de errores, más que para comunicarte con el usuario, sería para comunicarte con desarrolladores que van a ver este error.
00:03:55
De hecho, muchas veces este System.er, en vez de que escriba en consola, como hacemos nosotros normalmente porque no lo tocamos, se redirecciona a un fichero. De esta forma, cuando hay errores, no aparecen al usuario, pero se apuntan en un fichero de log por ahí en algún lado.
00:04:24
De esta forma, en cierto momento, si viene el técnico y dice, mira, me pasan estos errores, a veces me hace caos,
00:04:42
pues el técnico puede acceder al fichero de log y ver qué ha pasado, cuáles han sido los errores
00:04:48
y en qué días normalmente, quién es el usuario que las ha hecho, etc., etc., etc.,
00:04:55
para intentar sacar algo en claro de qué está pasando.
00:05:01
Entonces, cuando pasa una excepción, nosotros veremos en system.error,
00:05:07
Entonces los que ven rojo salen toda esa información que sustancialmente es la pila de llamadas de métodos.
00:05:11
Es decir, quién ha llamado qué, quién, qué ha llamado quién, qué ha llamado quién, qué ha llamado quién, hasta dónde se ha verificado el error.
00:05:17
Entonces si yo tengo un index out of bound exception, pues me la he hecho en esta línea de mi programa, que ha llamado un método de otra clase que era siempre mi programa,
00:05:24
pero este método estaba usando un array que entonces era la clase que gestiona el array
00:05:37
que ya no es mi programa, ya es JDK, ya es algo a nivel más de Java Virtual Machine
00:05:41
y de allí abajo, abajo, abajo, hasta llegar a los puntos donde se ha explotado
00:05:47
yo puedo seguir esas llamadas para saber qué ha pasado, dónde ha sido el error
00:05:51
cuál es la línea que la ha provocado, pero a quién llamaba y quién estaba ejecutando en ese momento el procesador
00:05:57
para saber, para enterarme un poquito más de qué ha pasado en ese momento
00:06:03
Yo proporciono un mecanismo
00:06:06
Para controlar situaciones que normalmente provocarían
00:06:09
Interrupciones en ejecución
00:06:11
Permitiendo gestionar el comportamiento
00:06:13
Del programa en caso de error
00:06:15
¿Cuál es ese mecanismo?
00:06:16
¿El único mecanismo que sabéis vosotros de gestión de errores?
00:06:27
No
00:06:30
Try-catch
00:06:31
El try-catch es un mecanismo
00:06:32
De ejecutar
00:06:35
Este programa, este trozo de código
00:06:36
Si pasa algo
00:06:39
Recoge
00:06:42
sketch la excepción que ha sido lanzada
00:06:44
y a ese punto en vez de acabar el programa
00:06:46
ejecuta otro código
00:06:50
que sustancialmente lo que debería hacer es
00:06:53
o terminar bien el programa
00:06:55
diciendo, mira ha habido un error, lo siento mucho, ha pasado esto, hasta luego
00:06:58
o intentar recuperarse
00:07:01
decir, mira los datos que me has dado no están correctos
00:07:04
o has intentado un acceso que no podías o lo que sea
00:07:07
y volver al menú principal diciendo
00:07:10
venga, inténtalo otra vez, porque ha fallado la operación, pero el programa sigue funcionando.
00:07:13
Cuando yo pienso en los errores, a este tipo de cosas que pueden pasar, hay dos formas de gestionarlo.
00:07:22
Uno es el manejo de errores o la programación pesimista.
00:07:30
La programación pesimista es intentar crear formas, crear código que evita los errores.
00:07:34
proteger zonas peligrosas usando if o usando algún tipo de comando
00:07:40
que pueda verificar que lo que estás haciendo es correcto antes de hacerlo
00:07:46
por ejemplo preguntarse si un objeto no es null antes de utilizarlo
00:07:51
entonces si yo hago un if mi objeto not null
00:07:58
estoy activamente verificando que este objeto no sea null
00:08:01
si es null te diré, oye mira no lo puedo usar
00:08:07
Si no es null, ya lo puedo utilizar, evitando así un null pointer exception. Es pesimista porque principalmente estoy sobrecargando el programa de muchos if.
00:08:09
En un programa normalmente, la mayoría de las veces
00:08:26
Los objetos que uso no deberían ser null
00:08:31
Debería ser algo
00:08:35
Yo estoy en una secretaría para alumnos
00:08:36
Estoy gestionando alumnos
00:08:38
Mientras gestiono los alumnos, los cargo de la memoria
00:08:40
Los uso, los actualizo y cosas por el estilo
00:08:43
Siempre me espero que esté trabajando con un alumno
00:08:44
Es difícil que haya buscado un alumno
00:08:47
Y justo ese alumno me haya dado null
00:08:50
Y entonces ahora estoy trabajando con un objeto null
00:08:51
Sin embargo, en la modalidad pesimista
00:08:54
Lo que estoy haciendo es comprobando
00:08:57
Cada vez que uso un objeto
00:08:59
Si ese objeto es bueno
00:09:01
Y a lo mejor hace 3, 4, 5 comprobaciones
00:09:02
De maestro es null, maestro es mayor que 0
00:09:05
Y esto
00:09:07
Sobrecarga el programa
00:09:09
Crea más
00:09:11
O sea, lo hace más lento
00:09:12
Porque en un 99%
00:09:15
De las veces esto iría todo bien
00:09:17
Porque no es null y el valor es mayor que 0
00:09:19
Pero yo lo estoy comprobando igualmente
00:09:22
Cada vez, ¿vale? Serían estos if innecesarios. Y también, trabajando así, es bastante complejo identificar todos los posibles problemas. Y que este objeto podría ser nul, pero que este proyecto podría ser no nul, pero dentro tiene otra referencia a otro objeto y esa sea nul.
00:09:23
podría tener este valor que es mayor que 1 pero menor que 0
00:09:44
entonces, ¿me entendéis?
00:09:49
o sea, se necesita mucha experiencia y mucho control de todos los posibles errores
00:09:50
y cuando llegamos a sistemas muy complejos
00:09:55
pues que se me olvide alguno de estos tipos de controles es posible
00:09:59
entonces está el manejo de excepciones optimista
00:10:06
el manejo de excepciones optimista es un poco decir
00:10:09
cuando hay un trozo de código peligroso
00:10:11
que podría dar problemas
00:10:14
que podría hacer un acceso a null
00:10:15
que podría hacer un acceso fuera del array
00:10:17
pues tú ejecútalo
00:10:19
asumimos que no haya fallos
00:10:22
las veces que haya fallos
00:10:25
en vez de haberlo comprobado cada vez
00:10:28
hasta cuando no haya fallos para estar seguro
00:10:31
pues las veces que explotará
00:10:33
que dará problemas
00:10:35
pues allí te escribiré un trocito de código
00:10:36
para qué tienes que hacer cuando pasan estas cosas.
00:10:39
Y este es el try catch.
00:10:44
El try selecciona un trozo de código, esto se ejecutará.
00:10:46
Si va todo bien, el catch no sirve de nada.
00:10:51
Si dentro de este trozo de código pasa algún problema,
00:10:55
el catch podrá recuperar ese error y ejecutar un código que se ejecuta.
00:10:59
Tened en cuenta que el try no se ejecuta completamente. Si en la primera línea del try es donde surge el error, porque hago un null pointer exception y luego hay otras 10 líneas de código, estas otras 10 líneas de código no se han ejecutado.
00:11:06
En el momento en que se lanza la excepción, en el momento en que ocurre la excepción, pues se interrumpe el bloque try y se pasa al bloque catch.
00:11:21
Este de aquí podría ser uno muy genérico, porque cualquier excepción se pilla en el catch, luego veremos que podemos hilar un poquito más fino.
00:11:32
Es decir, si la excepción era esta, hace una cosa, pero si la excepción era esta otra, hace una cosa distinta.
00:11:41
dudas hasta aquí
00:11:46
entonces esto sería lo mismo
00:11:48
en versión
00:11:53
pesimista y optimista
00:11:55
¿vale? en versión pesimista por ejemplo
00:11:57
yo pillo dos números
00:11:59
num denominador y antes de hacer
00:12:01
num dividido den
00:12:04
¿vale? que sería una fracción
00:12:06
pues lo que hago es comprobar
00:12:07
que el denominador no sea cero
00:12:09
porque si divido por cero me daría un error aritmética
00:12:11
una excepción aritmética
00:12:14
una divided by zero
00:12:15
¿vale?
00:12:17
Entonces, cada vez que yo hago esta operación
00:12:18
Pasaré por este if
00:12:21
Y todas las veces que yo daré un then
00:12:22
Que no sea cero
00:12:26
Pues igualmente haré este if y lo comprobaré
00:12:27
¿Sí? Entonces
00:12:30
Si esto lo hago un millón de veces
00:12:30
Haré hecho un millón de veces este if
00:12:33
Independientemente que el then sea cero o no
00:12:34
La versión optimista
00:12:37
Es decir, yo esto lo guardo en un try-catch
00:12:39
Si por si acaso aquí salta una
00:12:42
Divide by zero exception
00:12:45
o ArithmeticException o lo que sea
00:12:46
pues lo recojo con esta excepción de aquí
00:12:48
te digo, oye mira, no es válido
00:12:51
hacer esto
00:12:52
y sigo adelante
00:12:54
si esto lo hago un millón de veces
00:12:55
pues a lo mejor esta parte de aquí
00:12:57
la ejecutaré unas cuantas veces
00:12:59
pocas veces
00:13:01
cuando hay una división por cero
00:13:02
tened en cuenta que igualmente
00:13:05
el try-catch no es gratis
00:13:06
o sea, marcar un trozo de código
00:13:08
y vigilarlo porque si explota
00:13:10
pues si yo pillo un catch
00:13:13
pues tendrá su coste computacional
00:13:14
pero técnicamente debería ser inferior
00:13:16
a hacer explícitamente un if
00:13:18
sobre todo si luego este if
00:13:20
es complejo, porque un if
00:13:22
facilita si está bien, si yo para
00:13:24
encontrarme den tengo que acceder a un
00:13:26
método, hacer una llamada de método, el método
00:13:28
hace una operación y de ahí saca un dato
00:13:30
y cuando este dato lo comparo a
00:13:32
otras cosas, pues puede ser más complejo
00:13:34
hacer este if que hacer simplemente un traquecho
00:13:36
¿Dudas?
00:13:39
Clase exception
00:13:44
Cuando hay una excepción
00:13:46
La Java Return Machine crea un objeto de la clase Exception
00:13:48
O sea, existe una clase
00:13:51
Todas las excepciones que hemos visto nosotros
00:13:52
ArrayIndexOutOfBoundException
00:13:55
IOException
00:13:58
NullPointerException
00:14:00
Todas son de una clase
00:14:02
Son heredan de una clase
00:14:05
Que se llama Exception
00:14:07
Exception luego heredará de otras cosas
00:14:09
Hasta llegar a Object
00:14:11
En este objeto se guarda la información relevante del error
00:14:13
Entonces, este es como un paquete de información
00:14:17
Que crea la Java Virtual Machine
00:14:21
Cuando hay un error en tiempo de ejecución
00:14:23
Diciendo, toda la información que puede ser relevante
00:14:25
Sobre este error, la empaqueto en un objeto
00:14:30
¿Quién ha producido el objeto?
00:14:33
¿Cuándo lo ha producido?
00:14:35
¿Qué ha causado el error?
00:14:37
¿En qué método se ha pasado eso?
00:14:40
etc, etc, etc, todo empaquetado
00:14:43
bonito para que yo luego lo recoja
00:14:45
sería esto
00:14:47
sería esto, veis que aquí
00:14:48
exception e, esto es como
00:14:57
poner int x
00:14:59
pues esto estoy creando una variable e
00:15:00
de tipo exception
00:15:03
que será un objeto
00:15:04
exception, y yo luego allí
00:15:06
podré hacer algo con este objeto, podré hacer
00:15:09
e.printstack
00:15:11
o e.getMessage
00:15:14
o e.
00:15:16
y todos los métodos que puedan haber
00:15:17
en esa excepción
00:15:18
o sea que
00:15:20
también aquí estamos usando
00:15:22
mucho el concepto de
00:15:24
herencia
00:15:27
¿vale? porque todos son excepciones
00:15:28
pero luego dentro veremos que hay
00:15:30
distintas, entonces si yo
00:15:32
uso una referencia de tipo exception
00:15:35
puedo utilizar los métodos de exception
00:15:36
pero si luego puedo hacer un downcasting
00:15:38
de esta excepción a otras excepciones
00:15:40
más pequeñas, más concretas
00:15:42
y utilizar los métodos de ellas
00:15:44
Un mismo código peligroso podría causar distintos tipos de excepciones
00:15:46
La Java Art Machine creará un objeto a su clase más apropiada
00:15:53
Si el error ha sido porque ha cedido fuera de un array
00:15:56
Será un array index out of bound
00:15:59
Si el error ha sido porque el array era null
00:16:01
Pues será una null pointer exception
00:16:04
Si es un error porque escribí en un fichero
00:16:06
El fichero no existe
00:16:08
Será una input out of exception
00:16:09
Una IO exception
00:16:11
entonces aquí
00:16:13
hay la numpointer exception
00:16:14
numperformate exception
00:16:16
ioexception, io mogollón
00:16:19
manejo de excepciones finos
00:16:20
es decir que cuando yo hago un catch
00:16:25
en vez de poner algo así grueso
00:16:26
de píllame una cualquier excepción
00:16:29
y allí hago algo
00:16:31
pues yo puedo decir
00:16:33
oye mira te voy a dar varios bloques catch
00:16:34
y este catch
00:16:37
lo usarás si es una input
00:16:39
autoexception, este catch
00:16:41
si es una RuntimeException
00:16:43
este de aquí si es
00:16:45
una NumberFormatException
00:16:47
de esta forma podría dar mensajes
00:16:49
distintos en base
00:16:51
a lo que ha explotado, si me dice
00:16:53
ArrayIndex.topBound te diré
00:16:54
oye mira has intentado acceder fuera
00:16:57
del array y por favor revisa
00:16:59
la posición, si en vez es un
00:17:01
NullPointerException te diré, oye mira el objeto
00:17:03
al que intentas acceder es null
00:17:05
y por lo tanto no puede acceder
00:17:07
en vez de dar siempre el mismo error de error
00:17:08
cuanto más
00:17:11
y lamos finos, luego es más fácil
00:17:12
para los administradores, para los desarrolladores
00:17:15
entender qué ha pasado
00:17:17
y por qué ha ido mal
00:17:19
y por qué ha habido problemas, ha habido errores
00:17:20
en este programa
00:17:23
adicionalmente existe
00:17:24
un cache especial
00:17:26
que es el bloque finally
00:17:29
que es un bloque que se ejecuta
00:17:30
siempre, tanto
00:17:32
que haya habido un error
00:17:34
como que no haya habido un error
00:17:36
siempre se ejecutan las líneas
00:17:38
dentro de finally
00:17:41
Por lo tanto, imaginémonos una cosa de ese estilo
00:17:42
Está el bloque 1, luego está un try, está el bloque 2
00:17:47
Luego está un catch de ArithmeticException, ArithmeticException
00:17:51
Bloque 3, ExceptionError, bloque 4 y bloque 5
00:17:55
¿Qué pasa si no hay excepciones?
00:18:01
Que se ejecuta el bloque 1, luego se ejecuta el bloque 2
00:18:03
Y al final se ejecuta el bloque 5
00:18:07
El bloque 3 y el bloque 4 nunca se ejecutarán porque no ha habido excepciones
00:18:10
¿Qué pasa si hay una excepción de tipo aritmético?
00:18:14
Si empieza el bloque 1, el bloque 2 se ejecuta pero solo parcialmente
00:18:17
Porque en un determinado momento de este bloque habrá un error aritmético
00:18:22
Cuando explota la aritmética exception, pues se ejecuta el bloque 3
00:18:26
Y cuando se acaba el bloque 3, se ejecutará el bloque 5
00:18:31
Se sigue después del bloque try-catch
00:18:35
O la pregunta, ¿dentro del bloque C podría haber otro try-catch?
00:18:37
Sí, tranquilamente
00:18:42
Que dentro de este de aquí, o sea, dentro de un catch
00:18:43
Podría poner un try-catch
00:18:47
La idea es que en un determinado momento
00:18:48
Debería intentar de hacer cosas y explotar
00:18:52
Debería recuperarme o acabar o cosa por el estilo
00:18:54
Pero si fuera necesario, imaginaos que yo intento escribir en un fichero
00:18:58
Y ese fichero no existe, me salta una IO exception
00:19:02
Pues aquí digo, vale, si no puedes escribir en el fichero que te han dicho
00:19:05
Crea tú un fichero por defecto y ahora intenta escribirlo allí
00:19:10
Y si me pasa otro error porque el disco duro está lleno
00:19:15
Entonces no puedo crear eso, pues allí habría otro try catch dentro del catch
00:19:18
¿Me explico?
00:19:21
Por ejemplo
00:19:23
Imaginamos que en vez de salte una null pointer exception
00:19:24
Pues ejecuta el primero y en el dos en un determinado momento hace una null pointer exception
00:19:29
dice es una aritmética excepción no por lo tanto este bloque no se ejecuta sería este de aquí que
00:19:33
es una excepción general pillaría todas las excepciones que no sean ésta por lo tanto se
00:19:39
ejecuta el bloque 4 y luego después el bloque 5 sí si le añadimos el final y vale sin excepciones
00:19:45
es bloque 1 hace el bloque trae completo luego después hace el final y luego después el bloque 5
00:19:54
si hay una excepción de tipo aritmético
00:20:01
lo que haría es el bloque 1
00:20:05
el bloque 2 a mitad
00:20:06
explota la aritmética exception
00:20:08
ejecuta el bloque 3
00:20:10
a este punto hace un finally
00:20:12
o sea ejecuta también lo que está en el bloque 4
00:20:14
y después sigue con el programa
00:20:17
después del track edge
00:20:18
si fuera una excepción de otro tipo
00:20:22
diferente
00:20:25
pues haría el bloque 1
00:20:26
luego el bloque 2
00:20:29
y explotaría
00:20:30
Haría el finally
00:20:31
Y luego posiblemente acabaría
00:20:33
Porque no se ha pillado
00:20:36
La excepción
00:20:38
Aquí no hay un catch
00:20:41
De exception
00:20:43
Por lo tanto el programa acabaría
00:20:44
Si yo la excepción no la recojo
00:20:46
El programa termina
00:20:47
Entonces no llegaría nunca al 5
00:20:49
Pero si el 4
00:20:51
El finally es como un
00:20:52
Una cosa final
00:20:57
Que haces
00:21:00
antes de decir ya está, aquí hemos llegado
00:21:01
pero si has pillado
00:21:04
el catch, la excepción
00:21:06
no ha llegado a la Java Virtual Machine
00:21:08
entonces no se ha bloqueado, entonces sigue adelante
00:21:09
entonces después de haber hecho el finally
00:21:12
sigo adelante, si en vez es una
00:21:13
excepción que no he manejado
00:21:16
y por lo tanto
00:21:18
ha subido hasta llegar a un momento en que
00:21:19
el programa se tiene que acabar
00:21:22
pero igualmente el finally se ejecuta porque por ejemplo
00:21:23
en ese momento tú guardas los datos importantes
00:21:26
en un fichero, escribes en pantalla
00:21:28
el resultado parcial actual para que
00:21:30
no se pierda todo y a ese punto
00:21:32
ya le dices a la máquina virtual haz lo tuyo
00:21:34
como el programador me ha dicho que
00:21:36
no tengo que recoger esta excepción
00:21:38
y por lo tanto
00:21:40
tiene que acabar, porque
00:21:41
si no recoges la excepción quiere decir que
00:21:44
quieres que se acabe allí
00:21:46
de forma bruta el programa
00:21:47
pero al menos esta parte finally
00:21:50
te ha permitido hacer una última pincelada
00:21:52
antes de
00:21:54
explotar
00:21:55
¿Vale? Se me ha
00:21:58
quejado Rosa de que
00:22:00
usáis la palabra explotar
00:22:02
como término técnico
00:22:03
en sus exámenes.
00:22:05
Por favor, explotar
00:22:08
no es técnico.
00:22:10
No, tampoco.
00:22:15
Que, extrañamente, son las cosas
00:22:20
que os quedan. Yo puedo estar 45 minutos
00:22:21
hablando de excepciones y
00:22:23
que es una excepción, nunca lo he oído.
00:22:25
Pero, exploto. Mira, hablamos de ti.
00:22:27
Pues nada, que
00:22:30
me paro, que es acabado.
00:22:31
Acabaremos el jueves
00:22:32
- Materias:
- Programación
- Niveles educativos:
- ▼ Mostrar / ocultar niveles
- Formación Profesional
- Ciclo formativo de grado superior
- Primer Curso
- Autor/es:
- Stefano Chiesa
- Subido por:
- Stefano C.
- Licencia:
- Reconocimiento - No comercial
- Visualizaciones:
- 2
- Fecha:
- 27 de febrero de 2025 - 12:48
- Visibilidad:
- Clave
- Centro:
- IES ROSA CHACEL
- Duración:
- 22′ 35″
- Relación de aspecto:
- 16:10 El estándar usado por los portátiles de 15,4" y algunos otros, es ancho como el 16:9.
- Resolución:
- 1152x720 píxeles
- Tamaño:
- 52.88 MBytes