2025-03-10-Programacion - 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:
Excepciones
alguna cosita por ahí alguna duda que queráis plantear antes de arrancar con la clase a contaros
00:00:02
yo cosas bueno al final sí bueno para dar una pequeña vuelta vale para terminar respondiendo
00:00:07
de la lectura en realidad se hace a través en las comunicaciones de nuestras aplicaciones de
00:00:47
enjaba se hacen a través de flujos de datos los flujos de datos son digamos para entendernos
00:00:53
podríamos considerarlo como unas tuberías que en un lado tienen pinchado
00:00:59
una entrada o salida de datos exterior y en el otro lado tenemos
00:01:04
puesto la conexión a nuestro programa.
00:01:08
En este caso es para leer datos, con lo cual el flujo de datos es de entrada.
00:01:12
Y en particular el flujo de datos que leemos es el flujo
00:01:16
SystemIn. Recuerda cuando utilizamos la clase
00:01:20
Scanner que en el constructor del objeto de la clase Scanner decimos
00:01:24
utiliza el flujo de datos SystemIn.
00:01:28
Los flujos de datos, es decir, para comunicar nuestra aplicación
00:01:32
con elementos externos, pues tenemos para la entrada
00:01:36
de teclado el SystemIn, para salida por consola
00:01:39
la típica, la estándar es la SystemOut.
00:01:43
De hecho, fijaros cómo a la hora de escribir en pantalla
00:01:45
directamente en lugar de utilizar clases adicionales
00:01:52
trabajamos sobre el propio flujo de datos.
00:01:55
Fijaros que ponemos System.out.println. Trabajamos ya directamente sobre el System.out. En cambio, la entrada normalmente la manejamos con otras clases adicionales que nos facilitan, digamos, un poquito la entrada.
00:01:57
¿Vale? Los flujos de datos, pues tenemos, ya os digo, el System Out para escribir, por ejemplo, en pantalla, el System In para leer desde teclado. Podemos tener flujos de datos a otras aplicaciones a través de conexiones con Socket, que son las típicas conexiones que utilizamos en nuestro día a día cuando comunicamos, por ejemplo, un navegador a un servidor web para descargar nuestra página de tenis de marca.
00:02:11
pues se establece un socket al servidor web desde el navegador.
00:02:37
Y bueno, y así con prácticamente todos los servicios.
00:02:42
Las comunicaciones se suelen hacer por sockets.
00:02:44
Diferentes lenguajes implementan conexiones por socket.
00:02:48
Java también lo hace.
00:02:51
Pues eso sería también un flujo de datos que comunicaría nuestra aplicación
00:02:52
con otro elemento externo.
00:02:55
Es decir, flujos de datos.
00:02:56
El de lectura, como bien comentas, es el systeming.
00:02:58
¿Qué me sucede con systeming?
00:03:01
Pues que la forma de trabajar, digamos, nosotros podríamos hacer lecturas, igual que hacemos un System.out.println, podríamos hacer directamente lecturas desde System.in, pero igual nos viene como bytes y tenemos que hacer una gestión un poquito más engorrosa, un poquito más complicada en nuestro código para terminar de convertirlo, por ejemplo, en cadenas de caracteres.
00:03:02
pero tenemos que convertirlas para
00:03:24
trabajar con ellas en ciertos casos. Entonces, ¿qué podemos
00:03:28
hacer? Pues apoyarnos en otras clases adicionales
00:03:31
que ya están disponibles en las librerías.
00:03:34
La clase quizás más cómoda es la Scanner, pero
00:03:37
en la Scanner, de hecho, siempre le decimos que
00:03:40
el flujo de entrada sobre el que queremos ir trabajando
00:03:42
con datos y Scanner ya nos da de forma adicional
00:03:46
un formato de estos datos, es el Sistening
00:03:49
cuando leemos directamente desde el teclado, pero en un objeto de la clase Scanner
00:03:52
podríamos coger y hacer la lectura no de System.in, sino hacerlo, por ejemplo,
00:03:58
de un fichero, que sería otro flujo de datos, y sobre ese flujo de datos
00:04:02
trabajar de una forma con datos formateados con Scanner.
00:04:06
Otra posibilidad para, digamos, que le pone una capa por encima al System.in
00:04:11
es utilizar la clase InputStream y la BufferReader y todo esto.
00:04:15
Ahora, en uno de los, no sé si es el siguiente tema o dentro de dos temas, hablamos de la lectura de ficheros y la lectura de ficheros siempre, aunque la podríamos hacer con escáner, pero siempre se suele trabajar con las clases estas, justo con la que propone el ejercicio para leer el system in, que es la input reader y la buffer reader.
00:04:22
puedes leer información
00:04:44
como bytes
00:04:46
o como caracteres
00:04:50
y para eso hay diferentes clases en las librerías
00:04:52
de Java
00:04:54
el hecho
00:04:55
de leer carácter a carácter
00:04:57
te lo permite la input stream
00:05:00
y luego si quieres tener un buffer para leer
00:05:01
de forma global conjuntos de caracteres
00:05:04
puedes meter todos estos
00:05:06
caracteres que lees en la input stream
00:05:08
en una buffer reader y ya tienes un buffer
00:05:10
con un conjunto de caracteres para leerlos de golpe, que es un poco lo que termina haciendo
00:05:12
cuando hacemos un redline en la escáner. Es decir, que son dos alternativas que nos permiten leer el system in
00:05:17
o leer ficheros, por ejemplo, de una forma más cómoda que leer directamente el system in
00:05:26
y que las tenemos ambas dos alternativas disponibles en librerías de Java.
00:05:32
¿Cuál es mejor o cuál es peor? Pues no sabría decirte, si una te gusta más u otra
00:05:38
pues puedes utilizar cualquiera de las dos
00:05:43
Es verdad que típicamente la lectura del teclado se suele hacer
00:05:46
más con escáner y la lectura de ficheros más con las otras
00:05:51
Si no tienes mucha intriga
00:05:56
en saber cómo funciona, te invito a posponerlo
00:06:00
dos o tres tutorías y cuando veamos el tema vamos a trabajar con esas clases
00:06:03
y hacemos también un acercamiento a leer el teclado directamente desde ahí.
00:06:07
Y si está muy intrigado, pues echamos un rato y lo vemos.
00:06:13
Sí, al final la clase Scanner,
00:06:18
bueno, no sé cómo está programada para serte sincero,
00:06:37
porque no me he ido a buscar su código y me he puesto a analizarlo,
00:06:40
pero sí que es verdad que nos devuelve directamente a través de un Redline
00:06:42
grupos de caracteres y digamos que
00:06:47
con estas otras clases lo haces
00:06:50
ese grupo de caracteres lo haces en dos pasos
00:06:52
directamente el flujo de datos te devuelve bytes
00:06:56
pero si normalmente en tu programa vas a querer
00:06:59
trabajar con caracteres pues digamos que le pones
00:07:02
una primera cubierta para que esos bytes
00:07:05
directamente los puedas leer tú ya como caracteres con un input reader
00:07:08
pero este input reader la idea es que leas
00:07:11
carácter a carácter, ya no byte a byte
00:07:14
sino carácter a carácter
00:07:16
y si quieres coger un
00:07:18
conjunto de caracteres con
00:07:20
una lectura de golpe
00:07:22
del input reader te va metiendo en un
00:07:23
buffer, es decir, va haciendo ahí una montañita
00:07:26
va agrupando los diferentes caracteres
00:07:28
que puedes leer y se escapa
00:07:30
de volverte, digamos, grupos
00:07:32
de caracteres, ¿por qué? porque está en un buffer
00:07:34
ya te hace la lectura directamente desde un buffer
00:07:36
en lugar de consultar cada
00:07:38
carácter directamente al flujo
00:07:40
desde donde se está recibiendo la información
00:07:42
entonces se hace como en dos pasos, es verdad
00:07:44
pero
00:07:46
lo dejamos, cuando lleguemos al tema
00:07:49
de ficheros ya veremos como lo tratamos
00:07:53
y si no entonces me das un tironcillo
00:07:55
de orejas y me dices, te recuerdo que habíamos dicho
00:07:57
de ver esto, pero ya te digo yo que
00:07:59
lo veremos porque es la forma de leer ficheros
00:08:01
y a ver
00:08:03
exactamente en que tema es
00:08:04
porque no recuerdo si es el siguiente tema
00:08:07
y si es el siguiente tema
00:08:09
colecciones de datos, mira
00:08:10
el siguiente tema es colecciones de datos
00:08:12
y el tema 10, que todavía no lo estáis viendo vosotros, es este
00:08:15
el de lectura y escritura de información y aquí trabajamos con
00:08:19
fíjate como por aquí aparece flujos de datos, por aquí habla de
00:08:22
ficheros, veis, esto lo tenéis vosotros ocultado todavía hasta que llega el momento de abrirlo
00:08:26
y por aquí, mira, escritura, lectura, información
00:08:30
ficheros binarios y de texto y mira, ves
00:08:34
justo por aquí como te habla de input stream directamente
00:08:39
y luego por ahí, mira, y buffer al reader, un poco esto es lo que me estás
00:08:42
refiriendo. Bueno, esta es otra clase, file reader, hay diferentes clases,
00:08:46
pero todas estas son las que trabajan con esto que comentas.
00:08:50
Y en este caso, fíjate cómo en sí la lectura
00:08:54
la hace en lugar de, en el constructor de este file input stream,
00:08:58
ya entraremos en detalle cuando lleguemos al tema 10, en lugar de poner
00:09:02
aquí systeming, pues la entrada, el flujo de datos de entrada es desde un fichero
00:09:06
que está en este caso en el fichero texto punto txt del sistema archivos en la carpeta c pues este
00:09:10
programa está pensado para que corra en un windows porque el sistema archivo está referido a hace dos
00:09:18
puntos barra barra entonces el tema 10 que a ver creo que lo tengo por aquí puesta las fechas pues
00:09:24
que la abrimos el mediador del mes que viene pues a mediador del mes que viene arrancamos con esto
00:09:31
Y lo vemos. Nada, nada, nada, sin problema. No sé, ¿alguna otra cosita por ahí queríais que comentáramos? Bueno, pues si no, os cuento la historia de lo que tenía pensado para hoy.
00:09:37
el tema este de control de manejo de excepciones
00:09:56
fijaros que abría la semana pasada y cierra mañana
00:09:59
para este tema en principio solo tenemos planificada
00:10:03
una semana, mañana abrimos ya el siguiente tema
00:10:06
que es el de colecciones, el de colecciones si que es un poco más amplio
00:10:09
vamos a ver que tiempo tiene, fijaros que tenemos prácticamente
00:10:12
un mes, este si que da, tiene más cosas que hacer
00:10:15
nuevos conceptos y tiene
00:10:18
tenemos que trabajarlo algo más
00:10:21
sabéis que, recordad que cuando
00:10:23
acabamos un tema, pues para cerrarlo
00:10:26
me gusta normalmente resolver
00:10:28
la tarea en una tutoría
00:10:30
entonces hoy
00:10:32
como la semana pasada
00:10:34
no tuvimos clase, verdad
00:10:36
o hace dos semanas, bueno vamos
00:10:37
con una pizca de retraso y como esta
00:10:39
tarea solamente dura una semana
00:10:42
este tema solo dura una semana
00:10:43
hoy tocaría, siguiendo esas pautas
00:10:45
corregir la
00:10:48
tarea del tema 7
00:10:50
pero antes de dejar pasar más tiempo con esta tarea ya que
00:10:51
mañana arrancamos con la unidad 9 pues he pensado que hoy
00:10:55
podemos pegar un repasillo a las excepciones
00:10:59
y bueno pues dejamos pendientes estas dos tareas y el siguiente día
00:11:03
dado que luego para el tema 9 tenemos prácticamente un mes
00:11:07
pues una de las tutorías, una tutoría y algo pues la resolvemos
00:11:11
las tareas para pegar otro repasillo a los conceptos de cada una de ellas
00:11:14
así que vamos con el tema de excepciones a pegar un pequeño repaso de la teoría
00:11:19
este tema, el tema de excepciones tiene dos bloques
00:11:26
aunque en realidad solamente venimos trabajando uno todo este tiempo
00:11:29
porque el otro lo veis algo en entorno de desarrollo
00:11:35
la primera parte es el control y manejo de excepciones
00:11:38
como os digo ahora entramos en detalle
00:11:41
y la segunda parte es, bueno pues habla de documentación del código
00:11:44
A este lo voy a dedicar dos minutos, sin entrar mucho más, ya os digo porque lo trabajáis más en entornos y si tuvierais dudas, pues bueno, me lo planteéis por los foros y otro día echamos más rato.
00:11:48
una parte cuando dedicamos
00:12:02
cuando vamos a hacer un desarrollo, pues en principio
00:12:07
tiene que ser una serie de pautas, una serie de procesos
00:12:11
y la asignatura está cerrada justo
00:12:14
en la parte de implementación, de pruebas
00:12:17
implementación y pruebas, es decir, hacemos un programa
00:12:20
mediante código y lo probamos ahí, le lanzamos unas cuantas
00:12:22
ejecuciones, pero en realidad
00:12:26
pensando en un proyecto global, pues estas son dos
00:12:29
fases entre muchas otras. Típicamente habría una definición
00:12:32
de requisitos, habría un diseño previo a ponernos a hacer el código
00:12:36
y posteriormente después de hacer el desarrollo del código y sus pruebas
00:12:40
habría una implantación y habría un posible mantenimiento correctivo
00:12:44
o evolutivo del código. En realidad la asignatura
00:12:48
se olvida de todo eso y nos quedamos centrados solamente en hacer el código
00:12:52
y en probarlo. Pero todas estas
00:12:56
otras fases traen consigo mucha documentación. Hay que definir muy bien el diseño cómo va y hay que hacer los manuales de usuario y los manuales de instalación del código.
00:13:00
Todo esto que en un ciclo completo de un proyecto habría que tener en cuenta. Como parte de esta documentación, Java nos permite meter ciertas pautas dentro del código
00:13:12
que luego de forma automática, a través de otro ejecutable diferente al intérprete de Java, genera una estructura de páginas y se autodocumenta el código, se puede decir.
00:13:26
Entonces, si nosotros dentro del código, el programa en Java que permite hacer esta documentación automática del código es Javadoc.
00:13:40
Aquí lo tenéis indicado. Cuando tú instalas el JDK dentro de la carpeta BIM, pues típicamente está el Java, el compilador Java C, está el intérprete que es Java, pues bueno, además de estos dos, hay otros cuantos ejecutables más que con el JDK se instalan y uno de ellos es, como os digo, el Javadoc.
00:13:49
cuando nosotros estamos haciendo código
00:14:10
recordad que tenemos la posibilidad de meter
00:14:15
comentarios o bien con dos barras
00:14:18
de estas, dos barras del 7
00:14:21
que viene con el teclado con el número 7
00:14:23
o bloquer de comentarios, si ponemos
00:14:26
barra asterisco, estos comentarios son
00:14:29
para meter varias líneas de comentario
00:14:32
y lo terminamos con asterisco barra
00:14:35
pues cuando queremos, una de las posibilidades
00:14:37
cuando vamos a utilizar las pautas que considera el programa
00:14:41
JavaDoc para implementar, para crear
00:14:45
de forma automática documentación, es que metas
00:14:49
comentarios, bloques de comentarios, entre barra, asterisco, asterisco
00:14:52
y luego terminas con asterisco, barra. ¿Qué pasa
00:14:57
con esto si se lo encuentra el intérprete de Java? Pues que como
00:15:01
empieza con barra, asterisco, asterisco, barra, no lo tiene en consideración
00:15:05
a la hora de ejecutar el programa. En cambio, si tú ejecutas Javadoc, este otro programa, al contrario que el intérprete de Java, lo que sí que intenta localizar en el código
00:15:09
es aquello que está encerrado entre estas pautas. Es decir, para el intérprete esto es un comentario a no considerar, pero en cambio para Javadoc esto es lo que le importa.
00:15:21
El resto no lo considera. Digamos que tiene la lógica inversa en tanto en cuanto considera las líneas que aparecen en los ficheros .java.
00:15:33
Y por aquí dentro lo que se hace es meter una serie de etiquetas que tienen que ser las que tienen que ser. Están especificadas en la forma de implementar documentación con javadoc.
00:15:43
y si tú en el código metes entre estos comentarios esas etiquetas,
00:15:54
pues luego cuando ejecuta el javadoc se viene a buscarlo dentro de los ficheros .java
00:15:59
y automáticamente el programa te crea esa documentación.
00:16:03
Ya os digo que tenéis algo de información aquí en el tema.
00:16:09
Nosotros no preguntaremos nada de javadoc en el examen
00:16:14
porque nos parece un poco más que está más planteado para entornos de desarrollo.
00:16:18
Pero bueno, ahí lo tenéis y si tenéis dudas, ya que aparece aquí en el temario, pues ya os digo, me ponéis alguna entrada ahí en el foro y si la podemos responder por el foro estos días, la respondemos y si vemos necesario, pues en la siguiente tutoría le echamos un ratillo.
00:16:23
Lo que sí que es particular de esta asignatura, aunque luego se vaya utilizando en otras si programáis en Java, son las excepciones, que es el otro bloque que se considera aquí en este tema. Está la parte de excepciones y la parte de documentación.
00:16:39
Entonces el 8A que trabaja con excepciones, ahora vamos al código como siempre para trabajar con ello, pero me parece interesante que veamos un poquito esta imagen, pues sigue esta estructura.
00:16:57
Recordad que decíamos que las clases en Java estaban organizadas en una estructura de árbol. Arriba del todo, estaría por encima de esta azuable incluso, estaría la clase Object. Siempre decimos que aunque en Java la herencia es única, toda clase hija solo puede tener una clase padre, sí que tiene ciertas características heredadas siempre de la clase Object.
00:17:11
Y parcialmente en ese árbol, esta es una zona en la cual tenemos también una estructura de clases.
00:17:34
Entonces, todo lo que tiene que ver con este tema, con lo que vamos a hablar ahora, cuelga de esta, de la excepción.
00:17:44
Y por encima tiene la clase throughable.
00:17:52
La clase está ThroughAble, o sea, si nosotros hacemos que una clase nuestra herede de excepción, pues tendrá las características de ThroughAble más lo que tenga aquí el excepción.
00:17:55
Ahora después vamos al detalle en código para ir trabajándolo.
00:18:09
Fijaros, el ThroughAble, pues Through es, si no estoy equivocado, es lanzar, ¿verdad?, en inglés, y con el Able, pues que tiene la capacidad de ser lanzado.
00:18:14
Entonces las excepciones, que es sobre lo que vamos a trabajar en este tema, se lanzan de forma automática, por eso heredan características de suable, cuando suceden ciertas cosas, ciertas cosas que son anómalas en nuestro programa.
00:18:24
Y esas cosas suelen estar encasilladas dentro de estas cajitas. Excepciones aritméticas, index out of bounds, such as element excesion, null pointer, illegal argument, bueno, pues con cualquiera de estas genera una situación anómala en nuestro programa que si nosotros consideramos, manejamos estas situaciones anórmalas, las trabajamos como excepciones.
00:18:39
excepciones y con el código correspondiente se lanza otras zonas de código para que trabajen
00:19:05
sobre ellas. Mirad, en los programas tenemos, yo creo, igual hay alguna más, pero bueno, yo considero
00:19:12
que tenemos tres posibles momentos en los cuales se nos pueden dar errores, momentos o tres posibles
00:19:20
situaciones. Un primer momento es cuando estamos codificando el programa, pues el IDE nos chiva
00:19:27
que eso no compila, pues porque tenemos errores sintácticos
00:19:33
dentro de nuestro código. Tenemos que resolverlo hasta que compile
00:19:37
y se pueda poner en marcha. Bueno, pues esos son errores de compilación
00:19:40
que quedan fuera del ámbito de lo que vamos a ver en este tema
00:19:44
porque todos estos posibles errores sobre los que vamos a trabajar
00:19:49
es cuando estamos ya ejecutando nuestros programas.
00:19:53
Y lógicamente los puntos class no se nos van a crear
00:19:56
si tenemos errores de compilación.
00:20:00
venimos programando desde hace tiempo y sobre el tanto esos errores de compilación que se nos van
00:20:03
presentando para que nuestro programa se pueda poner en marcha con lo cual esa faceta mejor o
00:20:08
peor ya la conocemos cuando ya tenemos que nuestro programa es capaz de ejecutarse pues es cuando se
00:20:13
pueden producir estos dos tipos de errores bien errores de los que aparecen colgando aquí de
00:20:20
error que no tiene más no no de éste no están colgando más estructura de árbol o de los de
00:20:26
¿Qué diferencia hay entre estos dos? Pues los errores que aparecen aquí etiquetados como error directamente son aquellos que se pueden dar en nuestro programa, pero nosotros no tenemos capacidad desde el código de gestionarlos.
00:20:32
hay un caso claro de esto
00:20:48
o yo por lo menos el que me parece a mi más claro y más entendible
00:20:53
imaginaros que estamos, nuestro ordenador
00:20:56
tiene un determinado hardware, una memoria RAM determinada
00:20:59
y bueno pues demanda muchos news nuestro programa
00:21:01
con lo cual vamos acogiendo más reservas de memoria RAM
00:21:05
y aunque no hagamos muchos nosotros en nuestro programa
00:21:07
pues a lo mejor están corriendo en paralelo otras aplicaciones diferentes
00:21:11
que también están cogiendo recursos de memoria RAM
00:21:14
Bueno, pues al final la memoria RAM de nuestro ordenador será finita, no será infinita, ¿verdad? Habrá un momento en el que se acabe y a lo mejor ante un nuevo new, el programa ya directamente dice, mira, ya el sistema operativo no es capaz de darme más recursos para seguir ejecutándome.
00:21:16
Eso es algo que se nos escapa a nosotros del alcance para poder controlarlo, con lo cual se producirá un error y ese error estará gestionado a través de este campo de errores.
00:21:33
bueno pues sabiendo que existe y habiéndolo identificado nos olvidamos de ello porque
00:21:46
nosotros en el código no vamos a poder manejarlo lo que sí vamos a poder manejar va a ser los
00:21:51
aquellos errores que cuelguen de este otro lado de excepción dicho esto y por ponernos un poco
00:21:56
en situación minimiza esta parte si luego tenemos que volver y no vamos al código vamos a crear un
00:22:05
proyecto como siempre si tenéis alguna duda que vaya surgiendo me vais diciendo
00:22:11
vamos a crear una clase
00:22:31
con cualquier nombre, este por ejemplo
00:22:33
y le metemos el main
00:22:43
vale, pues, ¿de qué estamos hablando?
00:22:57
fijaros, este programa, mirad, si cogemos y ponemos
00:23:03
aquí, vamos a hacer una primera
00:23:06
vamos a provocar una primera excepción ahí sencillota
00:23:08
vamos a poner para que sea más realista
00:23:11
no aparezca directamente ahí el error ya
00:23:15
en el código sea identificable
00:23:18
Vamos a definir un objeto de la clase Scanner, ponemos el flujo SystemIn, flujo de datos de entrada, y bueno, imaginaos que queremos hacer un programa, mirad lo que os comentaba antes, fijaros como la entrada de datos normalmente la encasulamos en otras posibles clases que tenemos en la librería de Java,
00:23:20
o en la clase scanner que también la tenemos en la librería de Java
00:24:05
porque nos resulta más cómodo trabajar con una capa, como si fuera una cebolla
00:24:10
con una capa más sobre un objeto de la clase scanner, pero en cambio
00:24:14
el flujo de salida de datos, System.out, lo solemos utilizar directamente
00:24:17
sin meterle ninguna otra capa de cebolla, aunque también lo podríamos hacer
00:24:21
pero típicamente lo solemos trabajar así.
00:24:28
Entonces, imaginaos que es un programa en el cual queremos dividir 10 entre el número que se meta por teclado. Introduce el número por el que quieres dividir 10.
00:24:31
lo cogemos por
00:24:51
teclado, me ha escrito aquí
00:25:05
lo que ha querido
00:25:08
nextline
00:25:09
hacemos la conversión
00:25:10
parseInt dsaus
00:25:18
y luego podríamos poner
00:25:21
aquí un
00:25:23
int i result
00:25:25
igual a i
00:25:27
dividido, que vale 10
00:25:29
dividido entre lo que metamos por teclado
00:25:31
bueno, aquí tenemos un programa
00:25:34
que, como veis, sin errores compila. Un programa que compila
00:25:48
sin errores. Y, bueno, aparentemente tendría que ir bien
00:26:01
en todos los casos. Si lo ejecutamos, decimos, bueno, pues 10
00:26:05
vamos a decir que lo divida entre 5 y me dice, mira, el resultado es 2.
00:26:09
¿Vale? Correcto, el programa está bien. Pero, ¿qué sucede si cuando lo ejecutamos
00:26:13
metemos aquí como dato un 0? Pues, bueno, se produce
00:26:17
una división por 0 y el programa termina. No es capaz de sacar el resultado
00:26:21
porque cualquier 10 dividido entre 0 nos da un valor de infinito y eso no lo puede, un número lógicamente infinito no lo puede gestionar el programa.
00:26:25
¿Qué se ha producido? Pues se ha producido una excepción. Esa excepción era controlable en el momento de compilación, no, el programa compila y de hecho para la mayor parte de los valores funciona bien.
00:26:34
Es un problema que se da en tiempo de ejecución. Fijaros cómo por aquí, ¿qué provoca cuando se genera una excepción de cualquiera de todas estas si no la hemos controlado? Ahora vemos cómo las controlamos. Pues que el programa pega un pete aquí y coge y termina directamente.
00:26:45
¿Qué sucede? Que se genera una excepción, fijaros por aquí.
00:27:07
Esa excepción en particular cuando se produce una división por cero es una excepción de tipo aritmético.
00:27:12
La excepción de tipo aritmético la tenemos aquí, ¿veis?
00:27:18
Se ha producido dentro de este árbol una excepción de este tipo.
00:27:21
Como no hemos hecho nosotros una gestión para controlar esa excepción, ¿qué es lo que ha pasado?
00:27:26
Pues que el programa ha terminado directamente.
00:27:31
Y lo máximo que tenemos aquí es una que nos chiva el tipo de excepción aquí en consola. Imaginaos que esto fuese un cajero automático, que queremos que tenga su funcionamiento las 24 horas del día durante todos los días de la semana.
00:27:33
En mitad de una de las operaciones se produce una división y esa división, este valor puede ir cambiando. En el 99,9999% de las veces el programa no tiene ahí un valor de cero y funciona correctamente, pero resulta que una vez sí que ese valor termina siendo cero.
00:27:49
¿Qué sucedería si no hemos hecho una gestión de esa excepción? El programa no finaliza y el cajero queda inactivo. ¿Es correcto una división por cero? No, esa división por cero no la vamos a poder gestionar, está claro.
00:28:10
pero tenemos la posibilidad a través de la gestión de excepciones
00:28:25
que vamos a ver aquí en este tema de estabilizar el programa
00:28:30
quizás enviar un informe, guardar en un fichero, hacer una entrada en una base
00:28:34
de datos diciendo que se ha producido esa situación anómala o directamente no hacer nada
00:28:38
y permitir que el programa siga ejecutándose
00:28:42
y no termina, con lo cual nuestro cajero ese servicio no lo ha podido dar pero sigue
00:28:46
el programa activo para seguir haciendo su funcionalidad
00:28:50
¿Cómo gestionamos las excepciones? Pues
00:28:54
en las zonas donde creemos que se puedan producir una excepción
00:28:58
decimos que intente ejecutarlas y le ponemos un try
00:29:02
intenta, en verdad la excepción se va a dar aquí, esto lo podríamos poner
00:29:06
fuera o lo dejamos ahí como queráis
00:29:14
vamos a dejarlo ahí, entonces dice intenta este código
00:29:19
que antes no teníamos el try
00:29:25
y captura la excepción
00:29:28
que se produce, que si no la estoy gestionando yo aquí a través
00:29:33
de código, lo que va a hacer va a ser terminar el programa y sacar un mensajito por consola
00:29:37
y ya está, pero aquí le estoy diciendo captúrala, la excepción que va a ser
00:29:41
lanzada, fijaros como aquí teníamos la palabra throughable
00:29:44
es decir, se lanza algo, se lanza una excepción
00:29:48
que nosotros podemos capturar con el catch esa excepción
00:29:52
y si no tenemos el try-catch, no la captura nadie y el programa termina.
00:29:56
Pero en cambio, si le ponemos un catch, estamos capturando esa excepción.
00:30:01
Y aquí podemos decir la excepción que queremos calcular.
00:30:05
Podemos poner excepción e.
00:30:09
Entonces, aquí lo que estamos diciendo, captura una excepción que se va a lanzar
00:30:16
y fijaros que aquí tenemos un objeto e de la clase excepción.
00:30:22
Este objeto se carga con información que se produce en el contexto del error. Cuando se produce el error en este contexto, se rellena antes de terminar un objeto y ese objeto, si lo estamos capturando, lo tenemos aquí como entrada.
00:30:26
Fijaros que esto se podría considerar como una especie de método. Tiene sus llaves y esto un parámetro de entrada que tiene catch como si fuese un método.
00:30:44
En los métodos, en los parámetros de entrada, en el momento que los llamamos, ponemos nosotros los datos.
00:30:55
no sé si es un método, tenemos aquí un public void a, ponemos int i aquí, pues este i en el momento que llamamos al método a, se lo pasamos justo en la llamada.
00:31:00
Si esto lo consideramos a todos los efectos como si fuese un método y esto es un parámetro de entrada, este objeto E de la clase excepción se cargará cuando sea llamada. ¿Y en qué momento se llama? ¿Lo llamamos nosotros por código o no? Se llama de forma automática por esta característica de ThroughAble, con lo cual en ese momento en el que automáticamente se llama, este objeto se carga con cierta información que tiene datos de lo que está sucediendo en el momento en el que se produce la excepción.
00:31:18
si ponemos aquí un system
00:31:48
aquí
00:31:51
podríamos poner el código que quisiéramos
00:31:52
podríamos dar de alta nuevas clases
00:31:55
acceder a una base de datos para
00:31:57
guardar un registro avisando
00:31:59
que en esta zona de código se ha producido
00:32:01
un error o podemos
00:32:03
poner un system of println para
00:32:05
nuestro seguimiento aquí en nuestro programa de andar
00:32:06
por casa, pero aquí podríamos poner
00:32:09
tanto código como quisiéramos en este
00:32:11
cache, vamos a poner aquí
00:32:13
error, entonces mira si hacemos
00:32:20
una ejecución
00:32:27
que no nos dé error, es decir, no ponemos un cero,
00:32:28
bueno, pues se ejecuta bien y fijaros como este system out de error
00:32:33
no nos lo muestra. Si en cambio provocamos un error,
00:32:37
fijaros como el programa ahora no ha dado
00:32:43
unos mensajes feos de error como antes, pero como se ha
00:32:46
producido el error, ha cogido y nos ha mostrado la gestión que
00:32:50
queremos hacer de ese error que hemos capturado
00:32:54
a través del catch, hemos puesto un system of println error, pues ahí tenemos
00:32:58
fijaros, aquí en la estructura esta, lo que hemos hecho
00:33:02
ha sido capturar una excepción del tipo exception
00:33:13
¿qué sucede si en el catch ponemos exception e?
00:33:16
pues que si se produce en la zona del código
00:33:21
donde tenemos el try, una excepción
00:33:25
de cualquiera de todos estos tipos, me da igual el que sea
00:33:29
el error que va a hacer la captura
00:33:33
del catch, todas estas excepciones, sea la que sea
00:33:38
son de tipo excepción porque están por debajo de ella en el árbol
00:33:41
la arithmetic excepción también es excepción
00:33:44
la index out of bounds excepción también es excepción
00:33:46
todas ellas, entonces cualquiera de ellas
00:33:50
si ponemos solo ese código, al capturarla con excepción
00:33:53
pues nos ejecuta las instrucciones que tengamos
00:33:56
dentro del catch. Fijaros, otra posibilidad
00:34:01
de excepción que tendríamos, voy a provocarla aquí antes
00:34:04
del try para que nos falle el programa y la podamos ver sin capturar
00:34:08
por aquí en la consola, pues imaginemos que tenemos un array
00:34:12
de caracteres que tenga, de caracteres no, de enteros
00:34:16
perdón, que tenga tres posiciones, pues si yo
00:34:25
cojo ahora y digo aquí que quiero que valga 6
00:34:29
aquel entero que en el array esté en la posición 6, pues lógicamente no existe
00:34:35
Si tiene tres posiciones, tendrá la 0, la 1 y la 2. Todo lo que no sea eso, no tendremos reservada en memoria RAM espacio para un elemento de tipo entero asociado a esta array en esa posición.
00:34:40
Entonces si ejecutamos por aquí, bueno me saca este mensajillo, da igual lo que ponga porque se va a producir sí o sí el error aquí, entonces aquí me vuelve a dar una excepción, fijaros como es una excepción y en este caso me está indicando que es array index out of bounds excepción.
00:34:54
excepción. Si nos venimos por aquí, fijaros, se ha producido
00:35:16
esta, index auto points excepción. Diferentes situaciones
00:35:20
en el programa provocan diferentes tipos de excepciones.
00:35:24
Si este código lo pongo aquí, es decir,
00:35:29
no lo dejo a las bravas aquí, que si se produce la excepción me finaliza el programa
00:35:38
y como mucho me saca esta información por aquí, pues si se
00:35:42
produce la excepción ya la capturará y
00:35:46
hará el tratamiento de esa excepción que tengamos puesto en el catch.
00:35:50
Fijaros que aquí el catch está a nivel de excepción,
00:35:54
como os enseñaba antes, está a este nivel, con lo cual cubre
00:35:59
tanto la aritmética excepción como la index out of both excepción,
00:36:02
ambas dos las cubre. Voy a comentar esto para que no se nos
00:36:06
produzca, bueno, no, lo voy a mantener y si ahora ejecuto
00:36:12
por aquí, se me viene aquí esta línea de código,
00:36:18
digo que el número sea un 2, voy a poner un 2 para que no se produzca excepción aquí en esta instrucción, le doy, se ejecuta esto bien, 10 dividido entre 2, 5, me saca el resultado por pantalla, hace esta reserva en el array y en el momento de este acceso se produce la excepción in this auto bounce exception, que lo que ha provocado como está dentro de un trade y el cache que tenemos es este, pues me ha sacado el system of println error, aquí lo tenéis.
00:36:22
Otra cosita os cuento, fijaros, voy a comentar esto para que no se produzca esta excepción y tenemos solamente candidato para excepción esta parte de código, esta parte de código en el caso de que por teclado metamos un 0.
00:37:00
Hacemos una ejecución normal, sabiendo que los datos no nos van a provocar excepción, pongo un 2, me da el resultado un 5, hace esta reserva que en realidad no lo estoy utilizando, de hecho me lo está chivando aquí yo creo, no es usada esta variable.
00:37:26
Como no tengo esto, lo tengo comentado, no se produce la excepción, no se viene por error y luego me saca el mensaje terminando el programa.
00:37:44
Bueno, todo lo razonable hasta aquí todo.
00:37:51
Si yo le pongo aquí un cero, bueno, pues vuelve a suceder algo parecido, pero se me viene por el error.
00:37:57
Y luego ya, una vez hecho eso, se viene aquí al terminando el programa.
00:38:05
Mira, si yo cojo y pongo aquí un mensaje que sea terminando el try, ejecuto, vuelvo a poner un código, un valor 2 que no me provoca el error, pues bueno, hace todo, me dice terminando el try, no me muestra el error y luego dice terminando el programa.
00:38:09
Y ahora hago una ejecución provocando un error y fijaros que cuando tenemos cierto código dentro de un try, en el momento en el que se produce una excepción, el resto del código que tenemos por delante ya no se ejecuta, que sería todo este en este caso.
00:38:37
directamente se viene al catch y una vez que termina el catch
00:38:56
continúa el programa, como ahora no me ha mostrado
00:39:00
el terminando el try ya que se ha producido la excepción
00:39:03
en este momento y lo que ha hecho ha sido
00:39:06
dirigirse la ejecución del código aquí al catch
00:39:09
me ha mostrado el error, ha terminado el catch
00:39:12
y el programa continúa, fijaros como
00:39:15
al haber hecho una gestión de captura de la excepción
00:39:18
el programa no ha terminado de golpe como sucedía
00:39:21
antes cuando no hacíamos esta gestión, que ya el código que hubiera por delante
00:39:24
no lo ejecutaba. En este caso, una vez que se ha producido el error
00:39:28
es verdad que esta parte del código no la ejecuta. Aquí tenemos una zona
00:39:32
de código donde deberíamos intentar estabilizar el programa.
00:39:36
Si han pasado cosas que lo deja el programa instable en lo que se ha
00:39:40
ejecutado por aquí arriba, ya que el resto de código no se ha ejecutado
00:39:44
vamos a dejarlo estable. Y luego posteriormente
00:39:48
después del catch, el programa sin terminar
00:39:51
continúa. Esto nos daría
00:39:54
garantías en ese supuesto
00:39:56
cajero que os decía
00:39:58
del que el programa iba a seguir ejecutándose
00:39:59
igual que
00:40:02
y en cambio si no hacemos el
00:40:03
trade catch, el programa finalizaría y no
00:40:06
se ejecutaría más.
00:40:08
Mirad, cuando ponemos
00:40:12
los catch
00:40:14
hemos utilizado un catch
00:40:16
común a este
00:40:18
nivel de la clase exception que nos recoge
00:40:20
todas estas, pero podría ser que nosotros quisiéramos hacer cosas diferentes en función del posible error que se dé.
00:40:22
En nuestro programa podríamos decir, mira, si se produce una visión por cero, yo quiero guardar un mensaje de error
00:40:30
en un fichero que se llama ceros.txt y si se produce en mi programa un error de un acceso, una raya, una posición
00:40:37
para la que no hemos hecho reserva, pues a lo mejor quiero
00:40:47
guardar información en un fichero que sea
00:40:50
Arrays.txt
00:40:53
Aquí que es lo que está pasando, que tanto si se produce una
00:40:55
como si se produce otra, si les comentamos
00:40:59
esta y pasa esta, nos vamos
00:41:02
a un catch que es común
00:41:05
ya que estamos capturando exception
00:41:07
y en ambos casos hemos tenido el mensaje
00:41:10
System.out.ln error
00:41:14
¿Qué sucede? Que tenemos la posibilidad de sacar mensajes diferentes en función de si lo que capturamos es de un tipo o es de otro.
00:41:17
Si nosotros podemos encadenar a un try más de un catch y en cada uno de estos catch tener una consideración diferente a la hora de procesarlo.
00:41:26
Por ejemplo, escribir en un fichero el error o en otro.
00:41:38
Si en lugar de poner aquí exception, yo cojo y pongo arithmetic exception, si lo que se produce ahora es un arithmetic exception, tengo la posibilidad de, en este catch, hacer un procesamiento diferente a si se produce cualquier otra excepción, dependiendo del código que ponga yo aquí.
00:41:41
entonces yo ahora ejecuto, la arithmetic exception se produce cuando hacemos aquí una división por cero, recordad, estoy provocando aquí, si aquí no meto un cero, el código va a darme excepción aquí por este acceso a la posición 6 de un array para el cual solo hemos reservado tres enteros, entonces aquí sin provocar error de arithmetic exception, fijaros como el procesamiento que me sigue haciendo es el de error, por pantalla,
00:42:20
Y ahora si cojo y aquí meto un 0 para provocar arithmetic exception, fijaros cómo ahora ya lo que hace es, bueno, pues me saca este mensajito de error. Error arithmetic exception. Es decir, he hecho un procesamiento diferente en función de la excepción que estoy gestionando.
00:42:49
Las excepciones, las capturas de las excepciones hay que ponerlas, hay que poner en el momento que se ejecuta la captura de una excepción el resto ya no se ejecuta. Fijaros que la aritmética excepción también es una excepción.
00:43:11
viendo aquí el árbol aritmética excepción también es excepción
00:43:29
cuelga de ella pero en el momento que se ha capturado como aritmética
00:43:35
excepción esta ya no se considera es decir cuando se produce
00:43:39
una excepción en un try en orden según
00:43:43
aparezcan en la ejecución irá evaluando a ver si la
00:43:47
excepción que se ha producido corresponde a una y cuando corresponde a esa
00:43:51
la ejecuta y una vez que ejecuta esa el resto de catch ya no
00:43:55
los tiene en consideración. Aquí hemos puesto la aritmética excepción, la otra que se nos había
00:43:59
dado era la de index out of bounds
00:44:06
excepción. Para no cometer error, vamos a hacerlo
00:44:09
así, mirad. Y así, con toda seguridad
00:44:14
la voy a poner ahí, un momento fuera del try
00:44:18
y así no lo escribo mal. Aquí lo tengo
00:44:22
bueno, lo he hecho esto para hacer ahora copy-paste
00:44:29
lo copio, lo voy a pegar ahí de momento, voy a hacer un try cast de nuevo y de la excepción, ahora le digo aquí animatic autoboss excepción.
00:44:32
Entonces, ¿qué sucederá? Ya quito esto de aquí, que solamente lo había puesto para que me saliera el mensaje aquí.
00:44:49
fijaros como en esta ejecución que lo tenía fuera del try
00:44:55
el programa se rompe por completo
00:44:58
y al contrario que cuando capturamos las excepciones
00:45:01
no sigue ejecutando, no nos ha sacado el mensaje terminando programa
00:45:03
que es lo que nos viene pasando hasta que hemos empezado
00:45:07
a trabajar hoy justo con la captura de excepciones
00:45:10
para controlar errores en el código
00:45:13
bueno pues ahora
00:45:16
¿qué estamos haciendo? le hemos puesto un catch
00:45:18
para la arithmetic exception, si se produce una de estas
00:45:23
le valdrá este catch, se dará cuenta y hará esta ejecución
00:45:27
si en cambio la excepción que se produce es
00:45:31
de que nos hemos ido fuera del índice en un array
00:45:35
pues no cuadrará con una arithmetic exception, en cambio cuadrará con esta
00:45:39
y el mensaje será este, es decir, en una situación podemos hacer una gestión del error
00:45:43
que codificaremos aquí cuando sea aritmética
00:45:48
y cuando sea que la RAI se va fuera de rango lo podremos gestionar aquí.
00:45:50
Y aún así podemos poner una excepción general aquí por si la excepción que se produce no es ni aritmética ni de índice fuera de rango,
00:45:55
no es ninguna de estas dos, en todos estos casos la gestión que se haría para la excepción sería la que pongamos a nivel general de excepción.
00:46:03
y la por ahí o tengo que salvar salvo algo que no se dé error aritmético en la excepción como
00:46:13
no es aritmético no me ha mostrado el aritmético ahora es que he puesto el mensaje en los dos
00:46:29
aquí a raíz fuera de rango ejecutó de nuevo algo que no sea aritmética entonces no ha entrado por
00:46:36
aquí no me mostró este mensaje entra por esta y me muestra este y luego existen otra etiqueta
00:46:46
que la etiqueta si no recuerdo mal finally cuando se les en esta podemos poner aquí también un
00:46:54
cierto código que se ejecutará por lo que creo recordar siempre y siempre es siempre tanto si
00:47:06
funciona el try como si se produce una excepción y nos vamos por el catch pues para que nos podría
00:47:12
servir esto pues imaginaros que yo que sé qué deciros que en todos los casos aunque aquí lo
00:47:21
tenemos cerrando el escáner queremos cerrar el escáner pero no lo hacemos aquí pues sería una
00:47:26
cosa podríamos poner aquí si el programa va bien yo voy a querer que se cierre el escáner con lo
00:47:31
cual hará el try completo sin irse por ningún catch pero si se va por un catch también ejecuta
00:47:38
el final y para probarlo vamos a meter un mensajito para que no lo muestren por consola
00:47:43
pasando por final y les hacemos aquí una ejecución vamos a hacer voy a parar un segundo voy a quitar
00:47:52
para que no de error la primera vez porque es que con esto me va de error sí o sí bueno para
00:48:08
que no me de error mira voy a hacer el acceso a la posición 2 que sí que existe con la reserva
00:48:14
de memoria entonces le digo aquí un 2 y mira ha ido correcto ha terminado el programa ha terminado
00:48:19
el try y dice terminando el programa, hago una ejecución por cero, en este caso se produce una excepción aritmética, me dice que pasa por finally, la ejecución ha venido por aquí, no ha completado, ya que se produce aquí la excepción aritmética, no continúa en el try, no me muestra el terminando el try,
00:48:26
es de tipo aritmético la excepción
00:48:54
con lo cual la captura este catch
00:48:57
me muestra este mensaje
00:48:58
y luego el finally como se ejecuta siempre
00:49:00
pues me lo muestra
00:49:03
y una vez que terminan los catch
00:49:04
el programa sigue ya que hemos capturado la excepción
00:49:06
y me muestra el terminando
00:49:09
el programa y bueno por
00:49:11
completar la jugada con estas
00:49:14
excepciones que tenemos puestas aquí voy a meter
00:49:16
un valor diferente de 0 para que aquí no
00:49:18
de error pero este me dará
00:49:20
un array index
00:49:23
autobounce excepción. Ahí lo tenéis y vuelve a ejecutar el
00:49:24
finally. Bueno, las
00:49:31
diferentes excepciones podemos intentar provocar algunas
00:49:39
de ellas. Mira, si creamos, vamos a crear
00:49:43
otra clase, vamos a crear, vamos a provocar algunas excepciones más
00:49:47
que vamos a llamar
00:49:51
manejo el cep. Y ya esta clase me va a
00:49:54
servir luego para enseñaros alguna cosa más. Bueno, aquí
00:49:59
tenemos una clase que está en el proyecto, en el mismo paquete
00:50:03
default. Entonces aquí podríamos coger y decir, vamos a definir
00:50:08
un objeto B igual a nul. No le hago un new. Aquí vamos a poner
00:50:19
un int y valor. Vamos a definirle un atributo de tipo entero
00:50:27
a esta clase, esta clase tendría sus métodos, sus atributos
00:50:33
entonces si yo pongo aquí b.yvalor igual a 5
00:50:37
¿qué sucede? que para b no he hecho
00:50:41
un new, con lo cual no hay reserva de memoria para sus valores
00:50:44
ni para, no hay reserva, no hay gestión de memoria
00:50:49
para los recursos que necesita el objeto b
00:50:53
en cambio estoy intentando acceder a uno de sus valores por aquí, entonces ¿qué sucede con el
00:50:56
programa de aquí un valor 3 fijaros que en este caso me vuelve a dar una excepción por este motivo
00:51:01
que es la excepción null pointer excepción null pointer excepción aquí la tenemos si este código
00:51:12
no lo traemos aquí es decir que ha sucedido que como lo teníamos fuera del try pues el programa
00:51:30
ha finalizado lo mismo que nos viene pasando termina de golpe no se sigue ejecutando fijaros
00:51:35
como no ha salido el mensaje, la misma idea que antes, si lo meto dentro de un try
00:51:42
pues pongo los catch por aquí que van a hacer la gestión
00:51:46
de esa excepción igual que del resto, la excepción
00:51:50
null pointer exception no la he metido como un caso particular dentro de los catch
00:51:54
con lo cual estará considerada en principio dentro de él la categoría
00:51:58
exception, con lo cual esa captura me dará un println error
00:52:02
pues hago una ejecución por aquí
00:52:06
fijaros como me ha dejado el error y pasa por el
00:52:12
finally, bueno pues otro tipo de excepción que podemos manejar aquí
00:52:17
lo está provocando el hecho de que no hayamos reservado memoria
00:52:20
para este objeto, pues si hacemos un new, manejo
00:52:25
le reservamos memoria como siempre, si ahora le damos aquí a la ejecución
00:52:28
fijaros como ya no ha saltado
00:52:37
excepción aquí en este acceso, como es lógico
00:52:42
me ha saltado, excepción aquí, de hecho la excepción que me ha capturado
00:52:44
es la de array index outbound excepción que es esta
00:52:49
o el acceso a la posición del array
00:52:53
para la cual no hemos hecho reserva, pero esta ya no, mirad otro tipo de excepción
00:52:56
yo creo que se produce cuando tenemos por ejemplo un objeto
00:53:06
de la clase scanner, intentamos hacer una lectura, un objeto de la clase scanner
00:53:11
cerrado, si hacemos aquí un next line
00:53:15
es decir, intentamos leer de un flujo de datos que está asociado
00:53:18
a un objeto de la clase Scanner cuando el
00:53:23
flujo de datos está ya cerrado, es decir, esa tubería que os decía que pinchábamos
00:53:27
en un extremo y el otro extremo de nuestro programa ha desaparecido esa tubería
00:53:31
entonces si intentamos leer a través de esa tubería, pues no existe
00:53:34
nos debería dar un error. Lo voy a poner fuera del try
00:53:38
fijaros, entonces aquí el programa va bien por completo
00:53:45
y en este caso, bueno, aquí me chiva un poco el mensaje
00:53:52
y me dice
00:53:56
Illegal State Exception, que es otra de las que andan por aquí
00:53:59
o Illegal, no, pues esta justo no está, bueno, es incompleto
00:54:02
por lo que veo este dibujo, ¿vale? Bueno, pues en diferentes
00:54:09
circunstancias tenemos diferentes tipos de excepciones
00:54:13
vamos a hacer una cosa
00:54:18
escáner para probarla capturándola y pasamos a otra cosa ya sigo contando claro lo que estoy
00:54:28
haciendo aquí es bueno utilizo el escáner y scan close lo cierro el escáner es decir aquí ya está
00:54:44
cerrado y aquí pero metiéndolo dentro del try intento hacer el next line para evitar que el
00:54:55
programa termine ya que lo estoy capturando con el try salvo por aquí y bueno pues ahora este el
00:55:00
tipo de excepción que se produce en la excepción que se produce aquí como no la tengo capturada
00:55:10
en particular se me viene por el excepción y me da un error bueno así para diferentes diferentes
00:55:14
excepciones se producen en diferentes situaciones continuamos mirad os decía que cuando se produce
00:55:22
una excepción y si consideramos los catch
00:55:29
como posibles métodos, estos catch están recibiendo aquí
00:55:35
un objeto. En este caso es un objeto de la clase
00:55:38
arithmeticException y claro, si lo consideramos como
00:55:43
una especie de método, en el momento en el que se lanza con el
00:55:46
throughAble este el catch, ese objeto se tendrá que pasar
00:55:50
información relativa a él y antes de lanzarlo se coge
00:55:55
información relativa al contexto en el cual
00:55:58
se produce esa excepción.
00:56:01
Mira, por aquí para el arithmetic exception
00:56:10
si yo pongo un System.out.println
00:56:12
de E, no sé si recordáis que en algún
00:56:14
momento os he contado que cuando ponemos
00:56:23
algo dentro del
00:56:25
el método println de la clase System.out
00:56:27
que es el flujo de salida
00:56:32
lo que hace es mostrar una cadena de caracteres que tengamos
00:56:33
aquí, pero aquí no siempre ponemos cadenas de caracteres, a veces ponemos
00:56:38
int i, int i a y ponemos aquí
00:56:42
más i a. Bueno, lo quito, se me queja
00:56:45
al mezclarlo con la e. Bueno, a lo que voy es que ponemos aquí i a, ¿veis?
00:57:09
Entonces, si println espera aquí una
00:57:14
cadena de caracteres, ¿por qué me acepta meter un i a?
00:57:17
Pues cuando estamos trabajando con el método println, cualquier
00:57:21
cosa que pongamos aquí, lo que hace es buscar
00:57:25
su método, lo que tenga
00:57:27
el método, ¿qué método era? A ver un momentito
00:57:33
que lo tengo por aquí apuntado creo en algún sitio
00:57:36
toString, sí, toString, no me acordaba
00:57:38
toda clase tiene un método toString
00:57:41
que es el que se llama para
00:57:46
convertir cualquier tipo de objeto, sea del tipo que sea
00:57:50
en este caso entero, a una cadena de caracteres
00:57:53
este método devuelve, es como si tuviéramos
00:57:56
un public string, devuelve un string
00:57:59
toString y ahora aquí en el código
00:58:03
tendrá que haber un return de algo que sea un string.
00:58:07
Entonces al ponerlo aquí es como si estuviéramos poniendo i.toString
00:58:14
llamará al método ese.
00:58:18
Vendría a ser algo equivalente así. Ahora después cuando hagamos
00:58:22
una excepción personalizada lo veréis. Y dentro
00:58:25
de este método cada clase habrá codificado aquí lo que queramos que se devuelva como una cadena
00:58:30
de caracteres en relación a ese método si nosotros ponemos aquí que lo que queremos es que se nos
00:58:36
muestre en el sistema println el objeto e lo que estará haciendo es utilizar el código que tenga
00:58:43
el método toString de la clase ArithmeticException para devolverlo como un string y que lo pueda
00:58:52
mostrar System.out.println. Vamos a ver qué es lo que nos muestra. Ponemos aquí un 0 para que se
00:59:00
produzca una ArithmeticException y me ha dado error porque se ha producido esta, ¿no? ¿Por qué me ha dado error?
00:59:10
este es ArithmeticException al dividir por 0
00:59:26
se ha venido por aquí
00:59:33
en lugar de venir por aquí
00:59:43
ArithmeticException, println
00:59:45
a ver, la voy a provocar
00:59:51
ah bueno, bien, se ha producido
00:59:58
bien, se ha venido por error
01:00:01
porque la excepción se ha producido en esta línea
01:00:02
del escáner que teníamos aquí cerrado
01:00:06
por eso no ha provocado una ArithmeticException
01:00:10
de división por 0
01:00:12
y se ha venido por el catch este del error
01:00:13
ya que ha sido esta línea la que ha
01:00:16
provocado la excepción
01:00:17
la comento
01:00:19
divido por cero y ahora
01:00:20
si se produce la aritmética excepción
01:00:25
y fijaros
01:00:27
que lo que me muestra
01:00:29
el sistema of println
01:00:31
de este objeto ha sido
01:00:32
este mensaje java lang aritmética
01:00:35
excepción división by cero
01:00:37
¿por qué tiene este dato
01:00:39
el aritmética excepción? pues lo tiene
01:00:41
porque se ha cargado en el objeto E cierta información.
01:00:43
Mira, si yo, como os decía, cuando ponemos algo aquí es equivalente a llamar al método toString de ese objeto.
01:01:03
Eso pasa siempre en el println, no solo para las excepciones, sino en cualquier caso.
01:01:11
Entonces, si yo ejecuto ahora la visión por cero, fijaros cómo poner el system.out.println de E
01:01:16
es lo mismo que poner el System.out.println.de.toString
01:01:21
con la llamada a este método.
01:01:25
¿Veis que aparece aquí por duplicado ese código?
01:01:27
Un poco por justificar lo que os decía antes.
01:01:31
Y otro método que tiene las excepciones
01:01:34
es el método getMessage.
01:01:37
Vamos a hacer una ejecución
01:01:41
con el método getMessage
01:01:43
para que veáis el contenido,
01:01:45
lo que nos devuelve el getMessage.
01:01:47
fijaros, el método getMessage es parte
01:01:49
de lo que nos devuelve el toString, que es esta descripción
01:01:53
es decir, el toString devuelve el tipo de excepción que se da
01:01:57
dos puntos y luego un mensaje indicando
01:02:01
el motivo de la excepción, entonces si utilizáis el método getMessage
01:02:05
te devuelve sin indicar la clase el mensaje
01:02:08
bueno, métodos que tenemos disponibles en todo tipo de excepciones
01:02:13
que se cargan en el objeto
01:02:17
que recibimos como parámetro de entrada, considerando
01:02:21
el cache como si fuera un método, cuya información
01:02:25
nos viene de forma automática, no la ponemos
01:02:29
nosotros, en el momento en el que se lanza la excepción
01:02:33
ya que es de tipo throughable, como hemos visto aquí.
01:02:37
Resumiendo por un momento, antes de pasar a la siguiente cosa que os voy a contar.
01:02:49
en nuestro programa se pueden dar errores de compilación
01:02:53
que los tenemos resueltos antes de tener un ejecutable
01:02:58
suelen ser de sintaxis, una vez salvados estos
01:03:01
los programas ya corren, pero pueden darse situaciones
01:03:04
en las cuales durante una ejecución
01:03:07
se produzcan ciertos errores
01:03:10
que no corresponden a la sintaxis sino al momento particular
01:03:13
de la ejecución, como aquí en el escáner metamos un 0
01:03:16
eso produce ciertas excepciones que provocan que el programa
01:03:19
se rompa. Si queremos evitar que el programa se rompa,
01:03:22
tenemos que decirle que vamos a intentar esa zona de código a sabiendas
01:03:26
de que podrían llegar a producirse ciertas excepciones. Si se produce
01:03:30
la excepción, como estamos en el modo de intentarlo,
01:03:34
las capturamos y aquí no resolvemos
01:03:38
el problema de que la división por cero no se pueda gestionar. De hecho, el programa
01:03:40
todo este trozo tenemos que tener en cuenta que no se va a ejecutar si se produce
01:03:44
la excepción. Pero sí que nos permite, por un lado, poner el código
01:03:48
que toque, que aquí estamos poniendo solo System.out para estabilizar el programa
01:03:52
y por otro tener la garantía que después de hacerse el catch, nuestro programa no
01:03:56
terminará y seguiremos aquí con el control de él. Ahora estamos mostrando solo un mensaje
01:04:00
pero si esto lo metiéramos dentro de un while, pues
01:04:04
ante un intento de error nos mostraría el catch y el while por aquí
01:04:08
nos volvería al código para seguir trabajando sobre esta misma zona de código incluso.
01:04:12
Si os surgen dudas, me avisáis, ¿vale?
01:04:23
Mirad, ahí en la teoría os aparecen también lo que son las excepciones personalizadas.
01:04:28
Vamos a repasarlas un poquito.
01:04:34
En Java, en todo programa, se consideran ciertas situaciones excepcionales, excepciones que son comunes a todo programa que tengamos en Java.
01:04:36
Da igual que sea un programa relacionado en un contexto o en otro.
01:04:49
si se produce una división por cero, pues eso es ingestionable
01:04:55
por parte del programa, con lo cual se producirá una aritmética excepción
01:04:59
como es un caso claro que se produce el 100% de las veces
01:05:03
por dentro de la arquitectura en árbol de clases de Java
01:05:06
han definido la aritmética excepción y nos dan la posibilidad de controlarla
01:05:10
como hemos estado viendo. Si accedemos a un
01:05:15
a una posición para la cual no hemos hecho reserva de memoria
01:05:18
pues pasa exactamente lo mismo, el 100% de los programas
01:05:22
tendrán esa casuística y si se da eso, como no hemos hecho reserva de memoria
01:05:26
todos ellos fallarán, pues como todos ellos fallan, vamos a tenerlo en consideración
01:05:30
en las librerías de Java y ya te lo dejo dentro de esta
01:05:34
estructura de árbol de excepciones. Pero luego
01:05:38
podemos considerar nosotros, en nuestros programas en particular, situaciones
01:05:42
excepcionales que no lo son para todos los casos
01:05:46
Y bueno, pues en ese contexto podemos tener en cuenta las excepciones que me parece que es de la que os habla en la teoría. Yo que sé, en el contexto de una aerolínea de aviones que no quiere vender la fila 13, pues bueno, porque son supersticiosos.
01:05:49
Entonces, si vas a hacer una reserva y dar un valor de número 13 a la línea, a la fila en la que vas a vender los asientos, pues tú en tu programa quieres que se gestione como una excepción, igual que está pasando aquí en la aritmética excepción, porque es algo que no es aceptable en tu programa.
01:06:06
Pero obviamente no puedes considerar el 13 como una excepción en todo programa porque es un número igualmente válido en el 99,9999% de los casos. Es un valor más. Con lo cual, no ha lugar el definir una excepción global para ese caso, con lo cual no está recogido en la librería de Java, pero sí puedo yo considerarlo en mi programa en particular.
01:06:25
Mira, cuando se produce una excepción, lo que estamos haciendo es utilizar, a través del throughable este, se lanza el catch y se le pasa un objeto de una clase que es aritmética excepción que está en las librerías.
01:06:50
Si nosotros queremos considerar una excepción particular, lo que haremos será definir nuestra propia clase en nuestro programa, independiente de las que ya están en las librerías, y gestionarla como un catch.
01:07:09
Para que nuestra aplicación pueda ser lanzada igual que lo son las que están puestas en las librerías, necesita tener recogidas ciertas características.
01:07:24
¿Qué podríamos hacer? Desconocemos cuáles son, la verdad, porque están programadas en las librerías de Java, pero si las conociéramos podríamos coger aquí nosotros en nuestro código, si consideramos este manejo de excepciones como esa excepción particular, y programarlas a base de métodos y a base de parámetros.
01:07:36
Sería una opción. Y la otra opción es, oye, todo aquello que hace que una clase, cualquiera de estas, se pueda considerar como para la gestión de excepciones que se produzcan en mi programa, todas aquellas características, voy a aprovechar que tengo en Java la característica asociada a la programación orientada a objetos de la herencia,
01:07:54
pues voy a intentar heredar todo esto para que se pueda comportar como una excepción y luego, junto con todo eso que heredo, igual que hemos visto en otros casos, voy a programar mis propios métodos para completar el funcionamiento que a mí me interesa de esa excepción, ya que es particular mía y quiero que se comporte de una determinada manera dentro de mi programa.
01:08:18
que es lo que nos puede dar todas esas características
01:08:39
de que tenga la parte de comportamiento de una excepción
01:08:44
pues la podemos hacer que herede de excepción
01:08:47
entonces si yo aquí pusiera otra rayita
01:08:50
y pusiera mi clase como hija
01:08:53
de la clase excepción, todo lo particular
01:08:56
que tiene excepción, que ya hemos visto que puede ser capturado
01:08:58
como una excepción aquí
01:09:01
lo tendremos disponible por herencia en mi clase y luego además
01:09:04
podré programar yo aquellas cosas que me interesen. En mi código normal, que lo tendré aquí en el main o distribuido en los métodos que sea mi código normal, lo que pasará es que dentro de un try se podrá producir, igual que se producen ciertas excepciones ya consideradas en Java, esta nueva excepción que estoy definiendo.
01:09:07
Y si se produce esa excepción, querré que se capture. Y si se captura, tendré que recibir como parámetro en este catch un objeto de la excepción nueva que es la mía particular. Y para que esto suceda, tiene que existir esa excepción en el programa.
01:09:29
Entonces, la clase en nuestro proyecto que vamos a definir como esta nueva excepción es la que he puesto hoy aquí, manejo de except. Este manejo de except, para que pueda trabajar dentro de un cache, tiene que tener las características heredadas de exception.
01:09:46
Pues, ¿qué hacemos? Pues, vamos a poner que extends de exception. Ya puede ser capturada como una excepción, porque todo lo que tiene exception lo tengo yo en mis objetos de la clase manejo except capturado por aquí.
01:10:04
fijaros, en el contexto del programa este del que hablábamos
01:10:20
vamos a suponer que a través del escáner hemos
01:10:32
int y fila, hemos dicho que esto
01:10:35
tiene, es la fila 13 para la que vamos a hacer la reserva
01:10:41
vamos a suponer que lo hemos cogido ese valor a través de por aquí el escáner
01:10:44
es verdad que
01:10:49
con un número 13 en un entero no va a haber una situación en la cual
01:10:51
se va a producir una excepción de forma automática como sucede aquí pero lo que sí puedo hacer yo es
01:10:57
mediante un if es decir si la fila es igual a la 13 oye este esta es la situación de excepción que
01:11:02
no quiero que se produzca en mi programa lo que puede hacer es que se lance una excepción
01:11:10
del tipo manejo de excepciones si es así el código que no me acuerdo bien con el
01:11:19
new, tendré que poner aquí constructor, efectivamente. Con lo cual aquí
01:11:25
lo que estoy haciendo es lanzar una excepción. Este through
01:11:29
new manejo excepciones es lo que no vemos en el código
01:11:32
y se lanza de forma automática cuando se produce una división por cero. Aquí
01:11:37
estaría pasando, aunque no lo estamos viendo,
01:11:41
lo hará por detrás la máquina virtual de Java, estará haciendo un
01:11:45
through new arithmetic
01:11:49
exception y aquí
01:11:55
estará pasándole un objeto de la clase
01:12:01
excepción, el que sea, yo que sé
01:12:04
este código ya os digo
01:12:07
es el que no vemos, pues estaría pasando algo
01:12:10
como esto, y aquí estaríamos
01:12:13
completando información, a punto
01:12:36
lo que sea, de lo que tengan los objetos de esta clase
01:12:38
igual a lo que toque, por aquí
01:12:42
Y luego, este objeto es el que le pasa aquí, en la llamada. Entonces, con esta llamada saltaría el ArithmeticException y la información de esta A que la hemos cargado aquí, la tendría este objeto E de ArithmeticException, como sucede en los métodos para poder trabajar con él aquí.
01:12:44
esto que no lo vemos, porque para estas que son generales
01:13:04
está oculto y lo hace directamente, entiendo que la máquina virtual por nosotros
01:13:09
para una excepción nuestra particular, lo tenemos que hacer nosotros
01:13:13
entonces aquí estoy lanzando un manejador
01:13:17
de excepciones, y aquí podría hacer
01:13:21
un catch, igual que estoy manejando esas, veis, el catch
01:13:24
como muchos otros, ahora me lo acepta bien, ¿por qué?
01:13:40
tiene la categoría de excepción
01:13:44
gracias a que hemos hecho
01:13:47
un extend de excepción
01:13:49
aquí. La lanzo aquí, la excepción
01:13:51
lanzo aquí la excepción
01:13:56
y si
01:14:02
hacemos una ejecución
01:14:14
fijaros como este
01:14:15
de la excepción me ha venido por aquí
01:14:26
me ha hecho un system.out
01:14:28
println que me ha dicho
01:14:31
el nombre de la excepción, el toString
01:14:33
me ha dicho el nombre de la excepción
01:14:35
y el mesis este me ha devuelto un null
01:14:37
es decir
01:14:39
he lanzado mi excepción con el through
01:14:43
en el try
01:14:46
igual que se producía el lanzamiento de otro tipo
01:14:47
de excepciones y lo he capturado con
01:14:50
el catch. Vamos a poner aquí
01:14:52
vamos a poner aquí otro mensaje más
01:14:53
anterior para
01:14:58
no tener dudas
01:15:00
de qué pasa por aquí
01:15:02
lanzando
01:15:03
veis pone lanzando manejo de excepciones
01:15:06
y estas tres líneas son estas tres
01:15:17
líneas que tenemos por aquí. ¿Qué es lo que
01:15:19
hemos dicho que se muestra
01:15:24
con el método toString o cuando no ponemos
01:15:26
el toString con el e, este e
01:15:29
transforma el e en el toString para cargarlo en el println.
01:15:32
¿Y qué está devolviendo el método toString
01:15:36
de mi excepción?
01:15:39
Está devolviendo manejo de excepción.
01:15:41
¿Qué podríamos hacer que hemos visto en
01:15:45
clases anteriores? Pues podríamos sobreescribir
01:15:48
el método toString para que el mensaje que nos muestre
01:15:52
la excepción toString nos resulte de interés
01:15:55
porque esto la verdad es que nos resulta de poco interés
01:15:58
esto que nos pone aquí manejo excepción nos resulta de poco interés
01:16:02
en cambio tenemos la posibilidad de controlar
01:16:05
el mensaje que vamos a devolver
01:16:08
al tener a nuestra mano
01:16:09
el código de la clase manejo toString
01:16:13
entonces si ponemos aquí un override
01:16:16
utilizamos la característica de la programación orientada a objetos
01:16:18
de la sobre escritura de métodos podríamos poner un public string
01:16:23
tu string return devuelvo desde tu string aquí pongo un cierto código y que me está haciendo
01:16:31
esto sobre escribir el método tu string que tiene heredado desde la clase excepción y
01:16:52
Y desde la clase excepción para arriba, posiblemente el de object, la clase excepción estará sobrescribiendo el de object probablemente,
01:16:57
pero si lo vuelvo a sobrescribir yo para esta clase, lo que me devolverá será justo lo que ponga yo en el método toString.
01:17:06
Estamos cogiendo por las manos la clase manejo excepción para poder dar los mensajes que a nosotros nos interesen, poder tener el control y poder dar los mensajes que nos interesen cuando se produzca esta excepción y no algo tan genérico como esto que lo tengo simplemente disponible porque hereda de la clase excepción.
01:17:12
Entonces, si yo ejecuto ahora por aquí, fijaros cómo el método, esta impresión y esta, realmente a lo que acceden, como venimos diciendo, voy a quitar el null este, a lo que acceden es al método toString del objeto de la clase manejoExcepciones.
01:17:36
Fijaros como pone aquí devuelvo desde tu stream justo lo que tenemos puesto aquí en el tu stream. Pero esto quizás todavía no sea algo muy útil, es verdad que vemos que nos devuelve lo del tu stream, pero nos gustaría tener todavía información más fina de cuando se produce esa excepción, por qué ha sido.
01:17:58
Entonces, imaginaros que, por ejemplo, son especialmente supersticiosos, y agrandamos un poquito el enunciado que tenemos en la teoría, y no les gusta ni vender la fila 13, porque está justo al lado la 14 tampoco.
01:18:21
Son así, ¿vale? En esta aerolínea. Entonces podríamos lanzar la excepción si se produce una reserva en la 13 o una reserva en la fila 14. Si hacemos esta ejecución, fijaros, nos dice devuelvo toString, lo que tenemos en el toString aquí. ¿Por qué? Porque hemos intentado hacer una reserva en la fila 13.
01:18:42
Y el mensaje que tenemos es devuelvo tu string. Y si ponemos aquí 14, pues yo espero que nos funcione también por este or que tenemos aquí. Vamos a verlo. Efectivamente funciona, pero dice devuelvo tu string. Pues lógicamente, ha lanzado la excepción y utiliza el tu string. Pues en ambos dos casos dice devuelvo desde tu string.
01:19:08
pero oye, es que nos gustaría
01:19:29
es verdad que eso provoca situación excepcional
01:19:32
queremos que se lance la excepción, manejo excepción
01:19:35
pero me gustaría saber si realmente se ha producido
01:19:37
porque la excepción ha sido en la fila 13 o en la fila 14
01:19:41
me gustaría que este mensaje, tener disponible
01:19:44
ese dato, se ha producido excepción pero porque se hizo una reserva
01:19:47
en la 13 o la 14, quiero hacer una estadística de futuro
01:19:50
de si realmente la gente cuando
01:19:53
hace su reserva sabiendo que esta fila no nos gustan intenta buscarnos las cosquillas más
01:19:56
reservando en la 13 o en la 14 a pesar de que me salta la recepción no tengo no tengo el dato aquí
01:20:02
porque lo único que tengo es que se ha producido la recepción con el devuelvo de tu stream donde
01:20:09
tengo el dato fijaros lo tengo directamente aquí en esta clase de momento no me gustaría tenerlo
01:20:15
aquí en el catch, me gustaría tenerlo aquí, porque es donde estoy
01:20:22
lanzando este system of println y es desde donde estoy accediendo
01:20:26
al toString. ¿En qué momento sé si
01:20:30
se está produciendo la excepción por la fila 13 o la 14? Aquí,
01:20:34
que es la zona donde se genera la excepción, donde tengo el try.
01:20:38
Es decir, aquí se produce el error y luego
01:20:43
el mensaje lo escribo aquí, que son sitios de código diferentes. ¿Cómo puedo
01:20:45
hacer llegar la fila 13 o la 14 a este catch? Pues fijaros, si yo cojo aquí, estoy creando un nuevo
01:20:50
objeto con el new que sabemos que lo captura aquí, la información que tengamos ahí. Entonces, vamos a
01:20:59
aprovechar que aquí estamos creando un objeto que luego lo tenemos aquí disponible para pasarle esa
01:21:06
información, que es esa información de contexto que os decía que tenemos aquí y que se carga
01:21:10
directamente en estas excepciones del sistema
01:21:16
cuando se genera la excepción. Pues vamos a utilizar ese truquito nosotros también
01:21:19
desde nuestro programa. Entonces fijaros, podemos coger
01:21:24
aquí en la excepción, pues este y valor lo podemos
01:21:28
llamar y fila, un entero de y fila. En esta clase, aparte
01:21:32
de tener todo lo que tengamos de excepción e incluso un método que hemos
01:21:36
sobrescrito como toString, pues vamos a coger y como tenemos
01:21:40
una clase, sabemos que podemos programarla, entonces podemos poner aquí un public
01:21:44
manejo, except, constructor
01:21:47
de la clase, acordaros, constructor, mismo nombre que la clase
01:21:55
no devuelve nada, pero no se lo indicamos con el void, y nos interesa
01:21:59
un constructor sobre el cargado del que no tiene ningún dato
01:22:03
que reciba en el constructor el número de fila
01:22:06
entonces ahora puedo hacer aquí esta variable, la información
01:22:15
que reciba el constructor en esta variable, que sabemos que esta variable al ser
01:22:21
un parámetro del método es local al método, podemos guardarla
01:22:25
en esta otra variable, en este otro atributo
01:22:30
que en este caso es de clase. Y como este es un atributo de clase, estará disponible
01:22:33
en todo este ámbito mientras exista el objeto. Entonces, si en este atributo
01:22:38
de clase somos capaces de guardar la fila,
01:22:41
va a resultar que va a estar disponible para todo el
01:22:46
objeto y dentro de este objeto tenemos toString, esta es una variable que
01:22:49
podemos utilizar en toString, entonces aquí en el constructor decimos
01:22:53
dis.ifila, con el dis nos referimos al
01:22:58
atributo, recordad que sea igual a ifila
01:23:02
al no poner el dis nos referimos a este, es decir el valor que recibe el constructor
01:23:05
me lo guardo en el atributo de clase, el atributo de clase
01:23:10
lo tengo disponible en toda la clase y en toda la clase
01:23:13
está por ende disponible en el toString. Entonces ponemos aquí
01:23:17
por reserva de la fila
01:23:23
el toString ya tiene información que tengo en este atributo
01:23:27
que lo he recibido en el constructor y el constructor
01:23:38
lo estoy llamando aquí. ¿En qué zona del código lo estoy llamando? En la zona
01:23:41
de código donde se produce la excepción. Fijaros, si yo pongo aquí
01:23:46
este ifila, resulta que si la excepción se produce por la fila
01:23:49
13, el ifila, se lo paso al constructor a través
01:23:54
en la llamada por el parámetro, que le llega aquí al constructor
01:23:58
que se lo guarda en el atributo de clase, y este atributo de clase
01:24:03
lo estoy utilizando en el mensaje de toString, y donde
01:24:07
estoy utilizando el método toString, en el
01:24:10
catch, entonces he pasado información del contexto
01:24:15
donde se produce la excepción, a la zona de código, a través
01:24:19
de el objeto este, donde manejamos esa excepción, entonces si yo ahora hago aquí una ejecución,
01:24:23
bueno, he metido esto y me ha producido una excepción diferente, que no tengo controlada
01:24:33
aquí, porque he metido una W en un número, o en el parseInt, de hecho, como esto ahora
01:24:37
no me interesa, voy a comentarlo, fijaros que el número de fila con el que estoy haciendo
01:24:43
la ejecución ahora es el 14, he llegado aquí
01:24:49
la ejecución, tengo una variable aquí, como he comentado arriba
01:24:53
sin definir, por aquí otra sin definir
01:25:02
ya compila, bueno fijaros como ahora ya
01:25:06
en los mensajes me dice aquí que la fila es la 14
01:25:15
y si tengo aquí un 13, vamos a hacer otra ejecución
01:25:20
pues ya me dice que la fila es la 13
01:25:23
He pasado el número de fila, en este caso, del contexto donde se produce la excepción a la zona donde se captura. ¿A través de quién? A través de este objeto que estoy recibiendo en el catch y que he cargado al hacer este new.
01:25:26
y la información se la he pasado a través de parámetros.
01:25:45
Fijaros que, pensad por ejemplo que, aparte, se está pidiendo por teclado
01:25:52
el nombre de la persona que está haciendo la reserva, Valeria.
01:26:00
Y en el mensaje, a la hora de guardarlo, me interesa guardar el número de fila
01:26:07
y el nombre de la persona que hizo esa reserva.
01:26:11
Pues, ¿qué tendré que hacer? Pues me vengo aquí,
01:26:14
defino otra variable de clase, string ese nombre
01:26:15
obligo en el constructor a recibir también el nombre
01:26:19
para poder guardarlo, pongo this ese nombre
01:26:26
igual a ese nombre, en el atributo de clase
01:26:33
guardo el valor que tiene la variable local
01:26:39
del constructor, recordad que si estos
01:26:43
nombres se podrían llamar de una forma diferente estas variables a estas, pero bueno
01:26:47
Aprovechamos, las ponemos iguales y así repasamos el list.
01:26:51
A través de este constructor ya tenemos la información que le voy a pasar aquí en la zona D, donde se produce la excepción, en el new, ¿veis?
01:26:55
A través del constructor, new, manejo, nombre del constructor, se lo paso aquí y me guardo esa información de estas dos variables locales que se han cargado en la llamada a dos atributos de clase.
01:27:07
Y estos atributos de clase están definidos en el ámbito de la clase en su conjunto, con lo cual disponibles en el método toString, entonces aquí podemos poner, fijaros, ahora ese nombre, quien sea, el nombre que sea, reserva la fila, y aquí ponemos la fila que reserva en el toString.
01:27:18
entonces ejecuto por aquí y ya dice Valeria
01:27:44
reserva la fila 13, bueno dos veces porque
01:27:51
en el catch recordamos el e y el toStream
01:27:54
si en cambio ser Valeria es Rubén
01:27:57
y en la fila 14
01:28:04
pues del contexto donde se produce la recepción
01:28:07
el nombre y la fila, se la pasamos nuevamente por aquí
01:28:10
y en el catch
01:28:13
con esa información disponible, pues ahora nos dice que
01:28:15
Rubén quien reserva la fila 14
01:28:19
Bueno, pues estas son las excepciones personalizadas. Una clase que definimos nosotros, que lógicamente no pertenece a las librerías porque no es una cosa general que se produzca en todos los programas, pero si es particular de nuestro programa, queremos que se considere como una excepción.
01:28:21
podemos definir una clase que para que tenga características
01:28:40
de ser capturada con el catch
01:28:44
necesita aquellas cosas que en las librerías
01:28:46
tiene programado exception o programado
01:28:50
o heredado desde throughable probablemente
01:28:53
pues nosotros obligamos a que
01:28:55
herede de exception con lo cual todas esas características ya las tiene
01:28:59
y por aquí podemos poner tanto código
01:29:02
como nosotros queramos nosotros particular de nuestra
01:29:05
clase que estará añadido aquello heredado desde excepción si alguna duda
01:29:08
se entiende bueno esto es si quieres manejar la excepción podrías utilizarlo
01:29:18
pero de los flujos de datos no tengo término de entender muy bien por ejemplo
01:29:41
de un sistema de
01:29:45
sí bueno o sea si solamente se le hizo al final y
01:29:49
no vas a hacer ningún manejo de la excepción posible de componer el ipod
01:30:10
puede poner aquí un System.out.
01:30:15
Si pones esto, oye, no me gusta
01:30:17
esta fila. Coge otra.
01:30:19
Pero bueno, si quieres
01:30:21
en una clase tener
01:30:22
todo un manejo así más especial
01:30:24
de la excepción, pues lo puedes
01:30:27
programar dentro de una clase
01:30:29
y hacerlo así.
01:30:31
Sería posible.
01:30:34
Sí, puede ser.
01:30:57
Puede ser.
01:31:01
Al final,
01:31:03
podría ser que si se da una determinada
01:31:04
situación, pues en el catch
01:31:08
realmente aquí puede dejar reflejado
01:31:11
el error 2047, si ha sido por
01:31:14
un error en particular y si ha sido por otro, pues a lo mejor
01:31:17
tienes otro catch
01:31:20
con otra excepción particular, otra
01:31:24
excepción que tiene otro código. Las
01:31:27
excepciones en líneas generales,
01:31:32
bueno, esto te permite generarlas tú particularizadas. Estas, ya os digo
01:31:35
que se lanzan de forma directa, suelen ser en situaciones en las
01:31:39
que el programa, pues bueno, es que esta no te determina el programa.
01:31:45
Esta en verdad es que la codificas tú. Pues si la excepción tiene un manejo
01:31:49
digamos más general, se puede decir. O sea, más código. Si simplemente
01:31:53
va a ser un mensaje en un ficherito que
01:31:57
guardas o que sacas por pantalla un mensaje, pues a lo mejor
01:32:01
no te vale la pena programar una excepción y lanzarla y simplemente poner aquí, escribir
01:32:05
aquí en el fichero, ¿sabes? Como veremos en el otro tema. Y no tratarlo
01:32:09
como una excepción. Porque aquí el programa no se te
01:32:13
rompe. No es como en estas otras excepciones que sí se te rompen. En estas
01:32:17
mal vas si no las capturas con un try-catch porque el programa se te
01:32:20
rompe. En esta particular, en realidad el programa no se
01:32:25
rompe. Si la fila no es la 13, pues ahí sigue, ¿no? Ejecutándose.
01:32:29
O sea, aunque tú funcionalmente no te gusta y lo puedes manejar de esta forma.
01:32:33
Si el tratamiento de que sea la fila 13 es simplemente sacar por pantalla un,
01:32:38
oye, que has puesto la fila 13, pues a lo mejor no te vale la pena montar una clase con una excepción
01:32:44
porque puedes poner aquí un system out, la fila 13 no es válida.
01:32:50
Si realmente tiene más proceso, pues a lo mejor te podría valer la pena hacer una excepción
01:32:54
y todo el código gestionado por la excepción meterlo aquí en una clase.
01:32:59
Esto podría ser una clase o desde esta clase llamar a muchas otras, hacer su base de datos o generar mensajes a otras aplicaciones.
01:33:03
Sí, bueno, un poco terminando de responder a lo que me preguntabas, que no sé si al final con lo que te cuento te he respondido.
01:33:20
Si realmente cuando se produce en una aplicación de un banco de cualquiera un error es porque la han gestionado aquí.
01:33:27
aquí han dicho si el número de fila es 13
01:33:35
esto lo considero un error y el error es 13 o 20
01:33:38
50 o lo que sea y ellos tendrán una tabla con
01:33:41
códigos de errores de diferentes situaciones. Dentro
01:33:44
del programa ¿cómo podrán haber gestionado ese error? Pues simplemente
01:33:47
si no es un programa que se vaya a terminar poniendo aquí un system out
01:33:50
o creando en código si es en Java una excepción
01:33:53
que procese esta situación. Entonces
01:33:56
se podría hacer de esta forma lanzando la excepción y
01:33:59
capturándola con el catch. Aquí
01:34:02
mirad otra cosa, por terminar de cerrar el círculo
01:34:04
de esto de las excepciones, entiendo que en verdad estamos yendo un poco rápido
01:34:15
no sé si os da tiempo a digerirlo, pero como no tenemos muchas semanas
01:34:20
para esto y me gusta intentar repasarlo cuanto más mejor
01:34:24
la gestión
01:34:28
de excepciones es, yo intento un código y yo
01:34:32
capturo los posibles errores que hay dentro de ese try
01:34:38
pero también tengo la posibilidad
01:34:41
de delegar
01:34:44
la gestión de los errores
01:34:46
es decir, yo puedo intentar un código
01:34:48
y no poner aquí los
01:34:50
cuts donde
01:34:53
lo gestiono, imaginaos que
01:34:55
tengo, bueno
01:34:57
que lo puedo intentar
01:34:59
delegar, mirad
01:35:01
voy a modificar un poco por aquí, me voy a
01:35:03
llevar este código
01:35:07
vamos a crear una nueva
01:35:09
clase en el proyecto
01:35:11
delegar vamos a poner vamos a llamarlo así vamos a crear un método public void generar el cep un
01:35:15
método y en este método vamos a poner un código que nos dé una excepción como los que hemos visto
01:35:42
por ejemplo a igual nos olvidamos un poco de nuestra excepción personalizada igual año
01:35:52
int
01:35:59
le damos un tamaño de 3, justo vamos a poner
01:36:00
el mismo que antes y ahora
01:36:03
hacemos aquí un acceso a la
01:36:05
posición 4
01:36:07
bueno, esto lo hemos hecho en otra clase, podríamos
01:36:08
no haberlo hecho en otra clase, de hecho
01:36:16
mira, vamos a hacerlo
01:36:18
dentro de esta misma clase
01:36:21
vamos a definir aquí
01:36:22
un método, public
01:36:25
voy a ponerle static, porque lo voy a
01:36:26
llamar desde el main, public static
01:36:29
void
01:36:31
delegar, es lo mismo ponerlo aquí que en la otra clase
01:36:32
pero que se quede un poco más recogido, y este código que habíamos puesto
01:36:40
aquí para provocar la excepción, lo ponemos
01:36:45
aquí, aquí no, aquí
01:36:49
en el método delegar, fijaros que esto genera una excepción, intenta acceder a la posición
01:36:54
4 cuando he hecho una reserva de 3, el método lo voy a poner en minúsculas
01:36:58
ya sabéis, todo este código
01:37:04
lo voy a comentar, que no nos esté molestando
01:37:09
y voy a hacer una llamada al método delegar, el main
01:37:13
irá por aquí, por delegar, llamará al método delegar y luego irá
01:37:25
terminando el programa, cuando llamemos al método delegar, observad como
01:37:38
aquí se produce una excepción de
01:37:42
index out of bounds, fuera de rango el índice
01:37:45
efectivamente, por aquí se produce
01:37:50
fijaros como me dice por aquí que la línea en la que se en la que sucede es en la línea en
01:37:54
delegar en la línea 84 aquí aquí podría yo coger y hacer un try voy a intentar este código con lo
01:38:00
cual estamos yendo a lo mismo que hemos visto antes en el método main catch excepción y la
01:38:13
captura fijaros no voy a poner ningún código aquí simplemente capturó para que el programa no se me
01:38:25
termine de romper, hará el catch que es nada, se terminará
01:38:30
a delegar y después de delegar continuará el programa
01:38:33
y ahora es previsible que saque este mensajillo.
01:38:35
Vamos a poner aquí,
01:38:40
tardamos un minuto y así vemos bien todo el recorrido
01:38:43
por caso de delegar, ponemos,
01:38:47
ejecutamos, efectivamente se produce
01:38:58
el error, pasa por el catch, ya no sé,
01:39:01
el programa no termina porque he capturado la excepción
01:39:04
y me dice terminando el programa.
01:39:06
El tema de delegar el error que se produce en este try me lo captura aquí.
01:39:10
Recordad que si esto no lo ponemos en un try, se nos acaba el programa.
01:39:20
Si lo ponemos en un try, gestión por aquí.
01:39:24
Pues puede ser que no queramos tener la gestión de ese error aquí y que no se nos acabe el programa.
01:39:28
Entonces, la opción que tenemos es, al método delegar, por aquí, le podemos decir que puede ser que lance la excepción, voy a ejecutarlo un momento para hacer copy-pega, y no es que tenga que escribirlo, la excepción que provoca es este, el de array index out of bounds.
01:39:36
podemos decir que este método no va a gestionar con un try catch
01:39:57
esta excepción, puede lanzar esta excepción
01:40:05
pero sí que sabemos que se puede producir
01:40:10
esa excepción, entonces aquí en esta cabecera, en la asignatura
01:40:13
en la cabecera de delegar, lo advertimos de esta forma
01:40:17
en algún momento durante esa ejecución puede ser que se llegue a dar esa excepción
01:40:21
que en realidad va a ser aquí, y ahora el try catch
01:40:25
lo ponemos aquí. Bueno, exception, vamos a poner en lugar de la general, vamos a poner
01:40:30
array auto both exception. Básicamente lo que decimos,
01:40:45
intenta ejecutar esto. Es verdad que en este trozo
01:41:08
hemos dicho que se podía producir esta excepción o no, quizás,
01:41:12
dependerá de cómo se dé la situación, pero aquí está, según el código, sí que se va a
01:41:16
producir. Y en lugar de tener un trade catch aquí, pues
01:41:20
intentamos delegar y el catch lo hacemos aquí. La excepción se produce
01:41:25
a la vista en el método main? No. ¿Dónde se produce?
01:41:29
¿Dentro de este try? Sí. ¿Aquí está a la vista? No.
01:41:35
Delegar está aquí y decimos que puede producir esa excepción y efectivamente
01:41:39
aquí la produce. Entonces la captura en el catch aquí. Esto es lo que
01:41:42
os hablo en los apuntes de delegar o de
01:41:47
creo que lo pone con el término delegar la excepción, pues al
01:41:50
método que está llamándome, en lugar de gestionar yo esa excepción, se lo paso
01:41:54
para que la gestión la haga este otro método. Entonces fijaros cómo efectivamente sale
01:41:58
lanzada excepción, array, auto bounce excepción, pues porque la ha capturado aquí.
01:42:05
Si no se produce la excepción, si ponemos aquí un 2, como no se produce la excepción, pues ahí está.
01:42:14
Bueno, pues se la pasamos a alguien que me está llamando para que tenga diferentes gestiones.
01:42:27
podemos decir esto en para qué podría valer pues bueno pues por ejemplo buscando un posible caso
01:42:33
imaginaros que estamos llamando a este método desde desde el main y también lo estamos llamando
01:42:39
desde bueno pues otro método diferente mira aquí tenemos este método vamos a utilizarlo bueno este
01:42:48
ponemos lanzado desde a fijaros aquí estamos llamando a delegar desde a y aquí lo estamos
01:43:11
llamando desde desde el mail si lo estoy llamando desde el mail me sacar este mensaje si lo estoy
01:43:24
llamando desde a mes se lanzará este otro donde pone esto entonces hacemos una llamada de a del
01:43:41
método a desde aquí voy a separar las largas con un sistema 30 ln para que veamos claramente la
01:43:47
diferencia de una de donde se está llamando al método de legar desde el mail por aquí y
01:44:00
y luego después de los asteriscos llamamos a, y es desde a desde donde se llama,
01:44:05
pues fijaros aquí el mensaje, en esta zona de código, por lo que fuese en nuestro enunciado,
01:44:11
nos interesaba que si se producía un array in this auto bout exception,
01:44:17
el mensaje a guardar fuese este, desde el main, pero si se llama desde a,
01:44:22
que el mensaje sea este otro, tenemos la posibilidad de diferenciar una gestión
01:44:27
de un ArrayIndexAutoVaultException en delegar
01:44:33
si la llamada se hace desde un sitio o se hace desde otro.
01:44:37
Bueno, pues nos da esa opción.
01:44:42
Si el try-catch lo tuviéramos aquí en delegar,
01:44:43
como llamamos a delegar en ambos casos,
01:44:47
el mensaje sería común.
01:44:49
Otra posibilidad es que, por ejemplo, desde el main,
01:44:52
por buscar otro momento en el que podríamos decir,
01:44:56
¿Y por qué vas a derivar la gestión del error? Pues imaginaros que tenemos un método delegar2 y quieres que tenga el mismo, siempre que llames a delegar o a delegar2, pues quieres que tenga exactamente el mismo comportamiento en el catch.
01:45:00
pues si aquí pones
01:45:22
delegar y delegar dos
01:45:24
si se produce la array
01:45:27
in this auto both exception
01:45:29
tanto en una como en otra
01:45:30
la gestión de ese error
01:45:32
va a ser común porque está dentro del mismo try
01:45:34
con este catch
01:45:36
y yendo un paso más allá imaginaros que
01:45:37
bueno pues ya aunque yo creo
01:45:44
no lo vamos a hacer entre otras cosas
01:45:46
por las horas y porque por la hora que ya
01:45:48
y porque tendríamos que desarrollar
01:45:50
mucho más código
01:45:52
pero aquí estamos haciendo el catch
01:45:53
este es el método main que ya es como muy final
01:45:56
pero si este método no fuese el método main
01:46:00
sino que fuese otro método que hemos llamado
01:46:02
que está capturando las excepciones de delegar
01:46:05
en este método que pudiera ser diferente de main
01:46:08
también podríamos poner un thrush
01:46:10
que lanza la array index vote of bounds exception
01:46:12
y entonces delegar se lo pasaría a este
01:46:18
que no lo gestionaríamos aquí y este se lo pasaría
01:46:21
a quien ha llamado a este método que en particular es el main
01:46:24
pero estamos haciendo la suposición de que fuese uno diferente
01:46:27
o sea que podemos ir digamos elevando
01:46:30
el error sin gestionar de método
01:46:34
en método hacia arriba y bueno todo así
01:46:36
muy concentrado y en dos horas
01:46:44
yo creo que lo que os contamos hay decepciones
01:46:46
lo hemos podido resumir un poquito
01:46:50
no sé si os he
01:46:53
generado más dudas de las que teníais antes de empezar
01:46:56
la clase o os he aclarado alguna, pero
01:46:58
bueno, esta es un poco
01:47:00
la jugada de las excepciones.
01:47:02
En la próxima
01:47:05
tutoría nos ponemos
01:47:06
un poco por orden a resolver las
01:47:08
tareas, vemos la tarea
01:47:10
del tema anterior y si terminamos empezamos
01:47:12
con esta y si no, en dos tutorías
01:47:14
hacemos la tarea de esta y volvemos a
01:47:16
dar otro repasín allá
01:47:18
a estos contenidos.
01:47:19
¿Alguna cosilla queréis
01:47:22
comentarme antes de terminar?
01:47:24
No hay dudas de momento. Bueno, si os surgen luego más adelante, pues ya sabéis, podéis ir
01:47:26
poniéndolas por ahí en los foros e intentamos aclararlas. Si no me decís nada, voy cerrando
01:47:39
la grabación y vamos terminando ya por hoy. Bueno, nada, vosotros, pues nada, os
01:47:46
- Materias:
- Programación
- Niveles educativos:
- ▼ Mostrar / ocultar niveles
- Formación Profesional
- Ciclo formativo de grado superior
- Primer Curso
- Autor/es:
- JM
- Subido por:
- Jose Manuel M.
- Licencia:
- Dominio público
- Visualizaciones:
- 35
- Fecha:
- 10 de marzo de 2025 - 19:24
- Visibilidad:
- Clave
- Centro:
- IES ALONSO DE AVELLANEDA
- Duración:
- 1h′ 47′ 58″
- Relación de aspecto:
- 1.78:1
- Resolución:
- 1920x1080 píxeles
- Tamaño:
- 237.19 MBytes