Oi, gente. Vocês me desculpem que eu estou com a cabeça assim, meio zonza, é uma situação excepcional hoje, mas vai dar tudo certo, a gente vai aprender sobre exceções, tratamento de exceções e linguagens orientadas a objetos, então vamos lá. Exceções. Motivação é o seguinte, imagina que você tem código, você quer escrever código para ler texto de arquivo e gravar vetor, por exemplo, então a gente poderia ter método chamado LerArquivo, por exemplo, que recebe nome de arquivo com parâmetro, ele vai ter que devolver esse texto do arquivo num vetor de caracteres. Como é que a gente poderia fazer? A gente poderia escrever código para abrir o arquivo, determinar o tamanho do arquivo, alocar a memória para guardar aquilo, ler o arquivo na memória, fechar o arquivo e devolver. Isso é o que a gente gostaria de fazer, mas quando a gente vai olhar para a linguagem de programação real, ainda mais se a gente quer fazer programa que seja robusto, esse programa tem que lidar com situações excepcionais, então o código nunca vai ser tão bonitinho assim, porque se o código for simplesmente bonitinho, ele vai estar ignorando qualquer problema, qualquer erro que vai poder estar acontecendo e, geral, quando você lida com leitura de dados, escrita de dados de outros dispositivos ou entrada de dados do usuário ou conexões de rede na internet, é muito comum que coisas deem errado, então, quantas vezes você foi numa página web e não conseguiu acessar porque caiu a conexão de rede? Isso é a coisa mais comum do mundo. Às vezes a gente tenta gravar arquivo e acabou o espaço disco, a gente tenta abrir arquivo e o nome do arquivo está errado, então essas situações excepcionais acontecem muito, então, para escrever código robusto, profissional, o que a gente teria que fazer é algo desse tipo, assim, por exemplo, abrir o arquivo, verifica se o arquivo foi aberto com sucesso, se foi aberto com sucesso, daí sim a gente vai lá determina o tamanho do arquivo, se conseguiu determinar o tamanho do arquivo, daí sim a gente vai alocar a memória, mas daí você tem que verificar se conseguiu alocar a memória, se conseguiu alocar a memória, daí sim a gente lê o arquivo da memória, mas a gente tem que verificar se conseguiu realmente ler o arquivo, se conseguiu ler o arquivo, daí sim a gente pode fechar o arquivo, aí a gente tem que verificar se deu certo o momento que a gente fechou esse arquivo e daí, se deu tudo certo, todos os casos, aí sim, a gente devolve o conteúdoLido. Na verdade, isso aqui é código bem simplificado porque cada desses "ifs" aqui, se a coisa deu errado, eu deveria gerar uma determinada mensagem de erro explicando o que deu errado. Então, na verdade, o código real vai ser muito mais complicado do que esse código que está aqui e você vê que o código fica muito confuso, esse monte de "if" tratando vários casos, infelizmente isso é uma coisa que é muito comum, principalmente se você for usar uma linguagem mais tradicional como a linguagem C, por exemplo, o código vai ficar cheio desses ifs, cheio desses casos excepcionais, o que é uma coisa meio feia. Felizmente, linguagens orientadas a objetos, tem jeito de resolver esse problema. Qual que é o problema? O problema é que o código do que precisa ser feito fica misturado ao código do tratamento de erros. Se a gente faz isso, o código fica difícil de entender, fica confuso, na verdade, isso também é mais lento para o computador executar. Sabe por que? Isso é detalhe do modo como o hardware funciona. Você já deve ter ouvido falar que os processadores têm uma coisa chamada memória cache, essa memória cache é uma memória muito rápida, que fica dentro do processador e a medida que você vai executando seu programa, o computador, o sistema operacional, vai trazendo pedaços do seu programa e colocando na memória cache. Quando esse programa está na memória cache, ele executa muito rápido, mas a memória cache é muito pequena, não cabe o programa inteiro na memória cache, então o que é que ele faz? Ele vai trazendo pedaços. Se você tem o seu código do que tem que ser feito, fica intercalado com o código do tratamento de erros, pouco do seu código vai caber na memória cache, porque boa parte vai ser código de tratamento de erros, então você não vai conseguir colocar todo o seu código na memória cache. O software vai acabar rodando mais lento, seu programa vai rodar mais lento; Se tivesse uma forma de concentrar só o código bom, separar desse código de tratamento de erros, que é código bom, mas é código que é excepcional, daí mais código que realmente vai ser executado nos casos normais vão caber na sua memória cache e os seus programas vão executar de forma mais rápida, então como que isso funciona? Como isso pode ser feito? A solução é o tratamento de exceções que existem nas linguagens modernas orientadas a objetos. Como é que funciona isso? A sintaxe é parecida na linguagem C++ e na linguagem Java. Essa ideia surgiu antes, Smalltalk, mas a sintaxe era diferente, então como aqui é Java, também é uma sintaxe parecida com C++. É o seguinte, aqui está aquele bloco de operações que eu gostaria de fazer. O que a gente faz? A gente coloca esse bloco dentro de bloco que a gente chama de try. A gente está falando para o computador "tente fazer isso, tente fazer tudo isso", por acaso, se der algo errado, daí a gente coloca esse trecho que se chama catch e a gente passa para parâmetro, uma exceção, e ele fala o seguinte, se der algum comportamento excepcional qualquer desses elementos aqui, daí sim o que vai acontecer é que essas operações vão gerar uma exceção e a gente captura aquela exceção aqui embaixo, então a gente trata, aqui embaixo vai ter código que vai tratar a exceção que ocorreu. A vantagem disso é que a gente consegue separar bastante o código normal, que é esse aqui, o código do caso normal do código que trata situações excepcionais, que fica separado alí embaixo, então fica muito mais claro para a gente enxergar e também, como eu falei, tem benefícios termos de desempenho. O software acaba executando de uma forma mais rápida, então agora eu vou improvisar aqui pouco eu vou abrir o Eclipse, então vamos abrir aqui novo projeto e eu vou chamar o projeto de "toda regra tem sua", esse é o nome do projeto, gostaram da piadinha? Toda regra tem sua exceção, mas meu projeto chama "toda regra tem sua" e daí eu vou criar aqui dentro uma nova classe, que eu vou chamar de leitor de arquivo. Aí eu já vou dar o método main alí, então eu já tenho minha classe leitor de arquivo, daí o que eu vou fazer nessa minha classe leitor de arquivo, eu vou chamar método chamado leArquivo e esse método vai devolver o texto lido, então, na verdade, vamos ver. Eu vou já imprimir, por enquanto, depois, se for o caso eu mudo isso. Eu vou imprimir o conteúdo devolvido pelo leArquivo. Agora tem que implementar o método leArquivo, eu vou fazer o método static, ele vai devolver array de caracteres leArquivo e eu vou fazer ele receber como parâmetro o nome do arquivo que ele vai ter que ler e daí o que é que a gente faz aqui? Eu vou usar, Java tem uma classe chamada FileReader. Vou fazer FileReader recebe new FileReader e a gente passa com o parâmetro do nome do arquivo. Ele está reclamando que o FileReader não conhece. É porque tem que importar aqui, FileReader. Pronto, importa o FileReader, tudo bem. O que é que ele está reclamando mais ainda? Primeiro, está reclamando que esse FR nunca é aberto, eu abri. Esse FileReader vai abrir arquivo e está reclamando que esse arquivo não é fechado. Todo arquivo depois de abrir tem que ser fechado, basta a gente dar close aqui, tudo bem. O que é que ele está reclamando mais? Ele está reclamando, a primeira coisa que ele está reclamando é que quando eu crio novo FileReader, passando como parâmetro o nome do arquivo, pode ser que aquele arquivo não exista e se aquele arquivo não existe, ele está dizendo que esse arquivo vai, apareceu alí escrito, vai gerar uma exceção chamada FileNotFoundException, então o que ele está dizendo é que quando você faz isso aqui, você tem que fazer isso dentro de bloco try catch, então é isso que a gente precisa fazer. Eu falo, tente fazer o seguinte, ler o arquivo e depois fechar e, caso dê errado, deixa eu fechar aqui, tem que fechar. Esse bloco, é o bloco e daí a gente fecha. Caso dê errado, vai receber uma Exceção como parâmetro e a gente vai ter que fazer algum código aqui para para tratar dessa exceção. Por exemplo o código pode ser algo do tipo não deu certo. Não deu certo, mamãe. [SEM_ÁUDIO] Tá vendo que hoje eu não estou com muita seriedade. E daí eu posso por exemplo, imprimir essa exceção que deu. Estão, ele vai explicar que tipo de problema que deu. Deixa eu ver, salvou tudo aqui? Deu algum erro aqui. Qual que é o erro que deu? Sim. Faltou o ponto e virgula. Isso é fácil. Deu erro aqui também. Qual que foi o erro aqui? Eu preciso passar como parâmetro os argumentos, por exemplo, argumentos. Vou passar o argumento zero como parametro. Arquibo(arg[0]) Args e zero. Pronto. Deu certo. Aqui ainda estou com erro aqui cima. O método tem que devolver alguma coisa do tipo char. Então eu preciso, eu não li o arquivo ainda. Para eu ler eu vou fazer o seguinte, eu vou criar então aqui posso criar fora do try que é array de caracteres nome eu vou chamar de conteúdo, que é o conteúdo do arquivo. Recebe mil char, sei lá. 1021 kilobytes. 1024 caracteres. E daí agora sim eu leio. Então, eu faço file reader ponto read e passo como parâmetro esse meu array. Que ele vai fazer? Ele vai ler do arquivo. Se estiver tudo certo ele vai guardar dentro do conteúdo. Deu certo. E daí eu posso, depois que eu fecho o arquivo, eu posso devolver posso devolver no final. Vou devolver aqui no final o conteúdo desse meu arquivo. Então, deu certo. Vamos tentar executar para ver o que acontece? Então, eu vou mandar aqui executar. Bomba. Espera aí. Ele está tentando executar outra coisa. Deixa eu ver. Vou executar aqui já o aplication. Isso. Pronto. Executou? Mas opa. Deu uma exeção. Que exceção que deu? Deu uma exceção nesse thread main. Então, note comportamento excepcional E daí o sistema de execução de java detecta que foi lançado uma exceção. Qual que é o nome da exceção que foi lançada? Java ponto lang ponto array index out of bounds exception. E daí veio esse comentário. O indice zero está fora dos limites para esse comprimento zero. Por que? Porque voltando aqui para o código deu erro aqui baixo. Eu fiz args de zero, mas o vetor args como eu não passei nenhum parâmetro, ele tinha comprimento zero. Então, não existe a primeira posição que é a posição zero. Então, o que aconteceu aqui? Eu tentei acessar elementos de vetor que não existia e daí o sistema de execução Java gerou uma exceção. Então comportamento excepcional e ninguém capturou essa exceção. Então, vem uma mensagem de erro no meu console, falando "Olha, o seu programa gerou uma exceção. E particular ninguém tratou essa exceção. Então, essa exceção foi jogada para o usuário. Que é uma coisa, a gente vai ver daqui para frente é ruim. É legal se o próprio programa tratar da exceção. Então, particular, se eu aqui colocasse algum tratamento de exceção. Então, a gente colocar try. Tenta fazer isso aqui. Caso, daí eu até vou copiar aqui, caso dê algum problema. Você captura essa exceção, e daí você imprime aqui. Não deu certo mamãe, eu vou colocar aqui papai para diferenciar. Papi. Fica mais bonito até. Não deu certo papi, e daí vamos ver executar. Olha. Você vê que ele não deu aquela mensagem vermelha. Não jogou a exceção na cara do usuário. Mas porque eu capturei aqui no meu código a exceção, ele imprimiu isso aqui, "Não deu certo papi" e daí eu mandei imprimir a exceção que foi gerada. Nesse caso, a exceção que foi gerada ele imprime tudo isso aqui. Imprimiu a classe. Essa é a classe do tipo da exceção. Então, é a classe array index out of bounds exception. E esse aqui é comentário sobre que tipo de index out of bounds exception deu. Ele falou que o índice era zero. Então, eu preciso passar como parâmetro. Então, vamos aqui no run configurations. Para determinar o parâmetro. Então, eu vou passar como parâmetro com primeiro argumento, o nome de arquivo. Deixa eu pegar arquivo que eu tenho aqui de verdade. Deixa eu ver, eu estou aqui no diretório 'iii' tem arquivo aqui. Tem esse aquivo temp ponto c. Temp ponto c, deixa eu ver o que que tem dentro. Ele é código linguagem C. Arg. Linguagem C. Mas tudo bem. tudo bem, são exemplos. São arquivo texto. Eu vou ler esse arquivo texto. Então, eu vou botar o nome do arquivo. Então, o nome do arquivo vai ser o diretório aqui, barra. Então, o nome do arquivo, vai ser isso aqui barra temp ponto c. E agora vamos mandar executar. Olha, não deu mais aquele. Não deu aquele erro. [SEM_ÁUDIO] E deu certo. [RISOS] Não deu aquele erro, e ele fez tudo qu eu 'iii'. Tá vendo aqui ele imprimiu aqui, no console, o conteúdo daquele meu arquivo ponto c. Arg, c, socorro. Voltando ao código Java. Então, o que ele fez aqui? Abriu o arquivo viu que não tinha, que conseguiu abrir, gerar esse file reader, ele leu o conteúdo no nesse vetor de caracteres. Daí ele devolveu o conteúdo. Não teve nenhum caso excepcional. Tudo aqui deu certo. Então, não foi aqui para acessar caso excepcional. E ele veio aqui, e nesse caso conseguiu imprimir o conteúdo do arquivo. Note que se eu passar, vamos mudar aqui a configuração para dizer arquivo que não existe. Se eu botar arquivo não existe eu vou mudar aqui só. Vez de ponto c, ponto b. E mando executar. Daí ele gera exceção. Não deu certo mamãe. Foi lá cima a exceção. File not found exception. Ele gerou uma exceção e a descrição dessa execeção aqui. Ele falou temp ponto b. No such file or or directory. Então, agora a gente está capturando essas exceções e tratando essas exceções. Voltando aqui. O que mais a gente pode fazer. O que mais a gente pode fazer com exceções? A gente pode definir as nossas próprias exceções. Vocês viram que até o momento eu falei de exceções que já existem na que já vem prontas Java. Index out of bounds, file not found, coisas desse tipo. Mas se você quizer você pode criar uma exceção que tenha a ver com o seu programa, se você está fazendo campeonato de futebol, e tem algo alí nos dados do campeonato que não fazem sentido daí você pode gerar uma nova exceção, e daí você cria, sei lá se time tem menos de 11 jogadores, alguma coisa assim, você fala time incompleto exception. Incomplete team exception. Você pode criar, 'iii' como você faz isso, você cria uma nova classe, e depois você pode lançar exceções dessa nova classe que você criou. Vamos ver como que funciona isso. Por exemplo se eu quizer que, eu quero criar uma nova exceção aqui para esse meu leitor de arquivo. Daí o que que eu faço? Eu venho aqui no projeto, eu crio uma nova classe. Então eu faço new class. E daí eu vou chamar, sei lá. É arquivo feio exception. Ugly file exception. Ugly file exception. Uma brincadeirinha só. E daí eu digo que a super classe vai ser do tipo exception. Então, ele está mostrando aqui exception. Poderia ser também file io exceptio. Tem vários, tem toda uma hierarquia de classes que vocês podem dar uma olhada depois. A classe exception tem vários tipos de subclasse. Tem o IO Exception, que são exceções de entrada e saída. Tem outros tipos de exceção. Então eu poderia colocar. IO Exception aqui também. Vamos ver se tem se eu acho aí o exception. IO Exception. Aqui. IO Exception. Então eu vou criar essa classe. Aqui. Ugly file exception. Extends IO exception. Ele já fez automaticamente esse importe de IO Exception pra mim. Tudo bem. Eu poderia colocar alguns detalhes mais aqui nessa classe de exceção, mas não precisa. Podemos deixar por enquanto só assim. Uma vez que eu criei essa classe de exceptions, eu posso vir mais aqui no meu leitor de arquivos e falar por exemplo aqui se o eu poderia falar, se o arquivo é c if nome arq ponto. É deixa eu ver, contains, endswith, aqui [INCOMPREHENSIBLE] bonitinho. endswith.c, se é arquivo. C, eu falo nossa que arquivo feio e gero uma exceção de arquivo feio. Gostaram dessa? Como que eu gero uma exceção de arquivo C? Eu faço trhow, trhow significa lança, joga uma exceção Lança uma nova exception, o nome da exceção é uggly file exception, ugglyfileexception. Eu poderia passar como parâmetros aqui alguns detalhes sobre o porque o arquivo é feio, eu poderia falar é feio porque ele termina com .C, mas aí eu teria que mudar o construtor alí da uggly file exception para acessar isso como parâmetro. Ou ter outras coisas, então eu vou deixar o caso mais simples aqui, simplesmente vai gerar esta ugglyfileexception. Eu salvei aqui, vamos tentar rodar de novo? Rodando de novo, ele não achou o arquivo porque está como ponto B, deixa eu acertar para ponto C, onde que está, é aqui no run configurations, eu vou mudar o nome do arquivo de volta para seu arquivo ponto .C, pronto não deu certo, uggly file exception, como que você quis abrir arquivo .c? É muito feio!, mas na verdade eu estou querendo mostrar aqui para vocês, isso foi só para ilustrar que a gente pode criar as nossas próprias exceções e tem uma forma de a gente lançar uma exceção aqui, a gente pode capturar essas exceções também. Eu quero, vamos voltar aqui. Então, tem outra coisa, quando a gente está já vimos como criar uma exceção, lançar uma exceção, mas tem momentos que a gente tem que indicar novo método lança uma exceção, quando que método lança uma exceção? Tem dois casos, ou ele lança diretamente com esse trhows, com o throw que a gente fez. Então é aqui o throw, cadê o throw? Aqui. Throw new uggly fileexception, ele lança diretamente ou então, ele pode indiretamente, lançar uma exceção como, se ele usa método que lança uma exceção. Então, por exemplo, este filereader aqui eu não posso usar file reader sem ter o file catch simplesmente, porque ele vai dizer o file reader lança uma exceção. Então se você catura, se não faz file catch de file reader você tem que dizer isso de alguma forma, então quer dizer, vou mostrar aqui, apagar aqui algumas coisas só para ficar mais claro, vou apagar isso aqui, vou apagar todo tratamento de exceções. Vou deixar o que que aconteceria se a gente usasse simplesmente aqui, o file reader direto, sem tirando o tratamento de extensões deu erro de compilação, qual que é o erro ded compilação? Ele está falando, tem uma exceção que não está tratada, tem essa exceção file not found exception que você não tratou ela e precisa tratar esta exceção. Como que eu posso fazer? Ou eu faço o trial catch, que neste caso seria mais adequado, ou eu delego para quem for me chamar tratar esta exceção, se eu for fazer isso isso eu preciso colocar aqui no método, falar que esse método trhows file not found exception. Fazendo isso, note que sumiu, aqueles erros alí sumiram, sobraram alguns erros. Qual erro sobrou aqui? na verdade ele não conhece esse file not found exception, será que eu digitei algo errado? Vamos ver se ele tem que fazer import? Tem que fazer import, tudo bem. Fizemos import? Fizemos, pronto, sumiu aquilo. Agora então sumiu o erro da salinha, mas continua o erro do reader e do close, provavelmente ele vai falar que tem exceções o read ele gera a sessão exceção IOexception e o close gera IOexception. O que eu posso fazer também? O file not found exception acho que também é do tipo IOexception, então eu posso simplesmente aqui falar que ele gera uma exceção mais genérica, super tipo IOexception e bota aqui IOexception e pronto, deu tudo certo. Então, esta é uma outra forma, eu posso chamar métodos que geram exceção e eu não tratar da exceção e daí eu preciso dizer explicitamente que meu método, neste caso o método ler arquivo, ele vai gerar potencialmente esta exceção IOException, daí quem está chamando meu método vai ter que tratar isto. Neste caso específico o try catch aqui de baixo vai tratar, então se eu neste caso não está gerando uma exceção mas se tiver gerando alguma exceção neste três comando é o catch do main aqui que vai acabar tratando porque, no meu método, eu não estou tratando esta exceção, eu estou jogando esta exceção para a frente com esse throws IOexception, está bom? Então, é isso, resumindo, tratamento exceções organizada de lidar com situações excepcionais. E ele separa o código do caso normal, dos casos que algo dá errado. Você, quando você gera suas exceções, você deveria sempre que possível, usar alguma exceção que já vem pronta na linguagem Java. Por exemplo, se a ideia é dizer que o não encontrou o arquivo, você diz filenotfoundexception que é uma opção que já vem pronta. Se por acaso você precisa reportar novo tipo de situação excepcional que é bem específica do seu programa, daí você pode criar uma nova classe subclasse da classe exception, ou de alguma de suas subclasses e daí você usar o trhow para gerar aquelas exceções e note que a gente só gera exceções para casos de erro, casos que algo não esperado aconteceu, situações excepcionais. O fluxo normal de execução de seu programa, no caso normal não deveria gerar nenhuma exceção, exceção é para quando coisas dão errado e não para o fluxo normal do seu programa. Então é isso, espero que vocês tenham gostado para realmente aprender exceções vocês vão ter que praticar pouco. Obrigado, até a próxima e espero que vocês estejam curtindo a linguagem Java e orientação a objetos. Até a próxima!