quarta-feira, 15 de dezembro de 2010

[SO] Introdução


A maioria dos usuários de computadores já tiveram algumas experiências com os Sistemas Operacionais, mas mesmo assim é difícil a tarefa de reconhecer precisamente o que é um Sistema Operacional. O Sistema Operacional é uma camada de software colocada entre o hardware e os programas aplicativos. O sistema operacional é responsávelpelo acesso aos periféricos.

A função principal do Sistema Operacional é tornar a utilização do computador mais eficiente (obtida por meio da distribuição dos recursos) e conveniente (obtida escondendo-se do programador detalhes do hardware, em especial dos periféricos). Assim o sistema operacional fornece uma série de serviços como: gerência de memória, gerência do processador, memória virtual, sistema de arquivos, sistema de entrada e saída.

Os programas solicitam serviços ao sistema operacional por meio das chamadas de sistema que transferem a execução dos programas para o sistema operacional. A parte responsável para implementar as chamadas de sistema é o núcleo ou kernel.

Os sistemas operacionais podem ser classificados segundo alguns critérios. Os mais comuns são:
  • Número de Usuários
    • Monousuários: Projetados para suportar apenas um usuário.
    • Multiusuários: suportam várias sessões de usuários.
  • Número de tarefas
    • Monotarefa: Capazes de executar apenas uma tarefa por cada vez.
    • Multitarefa: Capazes de executar diversas tarefas simultaneamente.
  • Tipo de serviço oferecido ao usuário
    • Sistemas de processamento em lote (batch)
    • Sistemas de tempo compartilhado (time sharing)
    • Sistemas de tempo real (real time)
    • Sistemas Mainframe
    • Sistemas desktop
    • Sistemas distribuidos
    • Sistemas handheld
    • Sistemas paralelos

terça-feira, 14 de dezembro de 2010

[Arq e Org] Aritmética Computacional


Adição e Subtração

Na soma de binários os bits são somados um a um da direita para a esquerda, com os carries sendo passados para o próximo bit a esquerda. A subtração funciona de forma análoga, os bits são subtraídos da direita para a esquerda e os carries são passados da esquerda para a direita quando necessários. Exemplos: 5 = 0101; 6 = 0110; 7 = 0111
  1. 6+6 = 011110 + 0110 = 1110 (12)
  2. 7-5 = 0111 - 0101 = 0010 (2)
Tanto a soma quanto a subtração podem gerar overflow ou underflow se o resultado não puder ser representado pela quantidade de bits que formam uma palavra. O overflow ocorre quando soma-se dois numeros positivos e obtem-se um número negativo, ou o oposto. Isso ocorre porque foi utilizado o bit de sinal, gerado por um carry, para armazenar o valor pertencente ao resultado da operação. O underflow ocorre com um raciocínio semelhante o bit de sinal foi utilizado para armazenar um valor pertencente ao resultado da operação.

Operações lógicas

As operações lógicas mais utilizadas são: deslocamento de bits (para esquerda ou para direita), NOT, AND, OR e XOR. No deslocamento de bits a esquerda, perde-se o bit mais representativo e todos os outros bits a direita do mais representativo deslocam-se para esquerda e ao bit menos representativo é acrescido 0 (zero). O deslocamento de bits a direita funciona de forma similar. Todos os bits são deslocados para a direita, perdendo-se o bit menos representativo e no lugar do bit mais representativo é colocado um 0 (zero). A operação lógica NOT corresponde a negação. Um bit 1 (um) transforma-se em 0 (zero) e um bit 0 (zero) transforma-se em 1 (um). A operação lógica AND corresponde a operação E. A tabela verdade da operação AND é: 0 AND 0 = 0; 0 AND 1 = 0; 1 AND 0 = 0; 1 AND 1 = 1. A operação lógica OR corresponde a operação OU. A tabela verdade da operação OR é: 0 OR 0 = 0; 0 OR 1 = 1; 1 OR 0 = 1; 1 OR 1 = 1. A operação lógica XOR corresponde a operação OU EXCLUSIVO. A tabela verdade da operação XOR é: 0 XOR 0 = 0; 0 XOR 1 = 1; 1 XOR 0 = 1; 1 XOR 1 = 0.

[Arq e Org] Representação numérica binária


Números com sinal e números sem sinal

Para se representar números inteiros em computadores, é preciso transformá-los em binário, para isto são utilizadas várias técnicas, delas quatro se destacam: Sinal e amplitude/magnitude, complemento de 1, complemento de 2, notação em excesso.

Sinal e amplitude/magnitude

Neste sistema de representação numérica o bit mais representativo (mais a esquerda) representa o sinal. 0 (zero) indica um valor positivo enquanto 1 (um) indica um valor negativo. Os bits restante indicam o módulo do número (valor do número sem sinal). A faixa de representação para n bits é de [-(2n-1-1); 2n-1-1], ou seja, para n=8 a faixa de representação é [-127;127]. Nesse sistema o número 0 (zero) possui duas representações uma negativa e uma positiva.

Complemento de 1

Este sistema de representação numérica é muito parecido com o sinal e amplitude. O bit mais representativo (mais a esquerda) também representa o sinal. 0 (zero) indica um valor positivo enquanto 1 (um) indica um valor negativo. A representação para um número negativo em complemento de 1 pode ser obtida a partir da representação do número positivo correspondente invertendo cada bit da seqüência, ou seja, trocando cada 0's por 1's e cada 1's por 0's. A faixa de representação da representação em complemento de 1 é a mesma de sinal aplitude/magnitude, ou seja, para n bits é de [-(2n-1-1); 2n-1-1]. Assim como a representação de sinal e amplitude/magnitude o número 0 (zero) possui duas representações.

Complemento de 2

Complemento de 2 é o formato mais aceito e utilizado para representação numérica. O bit mais representativo representa o sinal. 0 (zero) indica um valor positivo enquanto 1 (um) indica um valor negativo. Para se obter o valor negativo de um número em complemento de 2 basta inverter todos os bits do mesmo valor em representação positiva e somar 1 ao bit menos significativo (mais a direita) desprezando o último carry, se houver. A faixa de representação para números em complemento de 2 é assimétrica, o número de representações negativas é maior que o número de representações positivas. Para n bits a faixa de representação é de [-(2n-1); 2n-1-1]. Neste tipo de representação o número 0 (zero) possui apenas uma representação que é positiva (00).

Notação em Excesso

Neste sistema de representação o bit mais representativo representa o sinal. 1 (um) indica um valor positivo enquanto 0 (zero) indica um valor negativo. A faixa de representação, assim como em complemento de 2, também é assimétrica e o número 0 (zero) possui apenas uma representação. A faixa de representação nesse sistema é [-(2n-1); 2n-1-1]. Nesse sistema cada número inteiro corresponde ao valor desejado em complemento de 2 acrescido de um excesso de 2n-1, onde n é o número de bits da representação, ou seja, se a representação possuir 4 bits o número 6 seria: 0110 + 1000 = 1110. A vantagem deste sistema consiste em que o maior número sempre será aquele onde todos os bits são iguais a 1 (um) e o menor número será aquele onde todos os bits são iguais a 0 (zero).

Tabela com a comparação entre os sistemas de representação

Binário (4bits)

Sinal e amplitude/ magnitude

Compl. de 1

Compl. De 2

Excesso de 8(n=4)

0000

+0

+0

0

-8(0-8)

0001

1

1

1

-7(1-8)

0010

2

2

2

-6(2-8)

0011

3

3

3

-5(3-8)

0100

4

4

4

-4(4-8)

0101

5

5

5

-3(5-8)

0110

6

6

6

-2(6-8)

0111

7

7

7

-1(7-8)

1000

-0

-7

-8

0(8-8)

1001

-1

-6

-7

1(9-8)

1010

-2

-5

-6

2(10-8)

1011

-3

-4

-5

3(11-8)

1100

-4

-3

-4

4(12-8)

1101

-5

-2

-3

5(13-8)

1110

-6

-2

-2

6(14-8)

1111

-7

-0

-1

7(15-8)



[Introd a Comp] Componentes do Computador


Um computador está organizado a partir de dois tipos de componentes:

Hardware: Corresponde a parte física do computador. São exemplos de componentes de hardware: processador, memória principal, dispositivos de entrada e saída, memória secundária.

Software: Corresponde ao conjunto de programas que exercem alguma função no computador. Podem ser classificados como software aplicativo (utilizados diretamente pelos usuários, como por exemplo jogos, editores de texto, tocador de música) ou sotfware de sistema (programas voltados para dar suporte funcional aos computadores, como por exemplo Sistema Operacional, firmware).

Principais componentes de Hardware

placa-mãe

Para integrar os componentes de hardware em um computador existe uma placa de suporte chamada placa-mãe. A placa-mãe é responsável por interligar os componentes de hardware e coordenar toda a transação entre os periféricos e o processador. Seus componentes principais são o chipset, BIOS (Basic Input/Output System), barramentos e slots.

O chipset é responsável pelo controle de diversos dispositivos de entrada e saída. O BIOS é o primeiro programa a ser executado quando um computador é ligado. sua função é de preparar o computador para que o Sistema Operacional possa ser executado e controlar o uso dos dispositivos, bem como conter informações de data e hora. O BIOS é armazenado em uma memória do tipo ROM (Read Only Memory) localizado na placa-mãe. Os barramentos fazem a interligação entre os dispositivos da placa-mãe. são divididos em via de dados, via de endereços e via de controle. Os slots são responsáveis por ligar os periéricos aos barramentos. alguns exemplos de slots são: AGP, PCI, PCI express, ISA.

Processador

O processador já foi abordado em post anterior.

Memória

Um dos principais componentes em qualquer computador é a memória. A função deste dispositivo é de armazenamento dados. As memórias possuem uma hierarquia quanto à velocidade de acesso aos dados como mostra a figura abaixo.



Registradores

Memória mais veloz, de menor tamanho de armazenamento e mais próxima do processador.

Memória cache

Uma das memórias mais veloz, porém de menor tamanho de armazenamento de dados. Devido a sua alta velocidade, a cache está presente nos processadores. Um processador pode ter vários niveis de cache.

Memória RAM

Segunda memória mais veloz, de tamanho razoável de armazenamento de dados. Também chamada de memória principal, pois é altamente utilizada pelos softwares.

Disco Rígido

Memória lenta e de armazenamento de grande volume de dados. Normalmente utilizado para guardar dados que podem ser acessados com baixa frequência. A lentidão deste dispositivo de memória dá-se por ser um dispositivo mecânico. Fisicamente um disco rígido consiste de um ou mais pratos metálicos e um braço mecânico que se move sobre estes pratos para realizar a leitura e escrita. Um disco rígido é subdividido em discos ("prato" metálico), trilha (região circular de um disco), cilindro (trilhas de uma dada posição do braço).

Para acessar dados em um disco rígido, é necessário informar à controladora o cilindro, a superfície e o setor a ser acessado. A essa ação chamamos de CHS (Cylinder, Head, Sector). Outro modo de se enchergar o acesso aos dados em um disco rígido é o procedimento LBA (Linear Block Addressing) que consiste em enxergar o disco como um conjunto de blocos, no qual cada bloco é um ou mais setores. o número de blocos é então convertido em CHS.

Placa de rede

Uma placa de rede é o dispositivo responsável pela comunicação entre computadores diferentes em uma rede. Sua função é controlar o envio e recebimento de dados entre a rede. Placas de rede podem ser com fio ou sem fio (wireless) e podem suportar diferentes arquiteturas (as mais comuns são Ethernet e Token Ring).

Teclado

O teclado é um periférico de entrada de dados utilizado na interface entre o usuário e o computador. O princípio de operação do teclado é muito simples e se acemelha a máquina de escrever. Cada tecla pressionada produz um símbolo ou é utilizado em conjunto com outra(s) tecla(s) para produzir ações predeterminadas.

Mouse

O mouse é um periférico de entrada de dados que foi criado após o teclado para auxiliar o processo de interação homem-computador. O princípio básico de utilização do mouse é como um apontador. O mouse possui poucos tipos de operações (click, duplo click, drag and drop e movimentação). Existem modelos de mouse com dois, três ou mais botões, e sua função depende do ambiente de trabalho do mouse.

Monitor

O Monitor é um periférico de saída de dados utilizado para se visualizar dados. Os monitores antigos eram monocromáticos e evoluiram até altas resoluções gráficas. Os modelos antigos de monitores eram, assim como as televisões antigas, de tubo de raios catóticos. Atualmente existem modelos de LCD e LED.

Impressora

As impressoras são dispositivos de saída com a função de imprimir(seja em papel, filme plástico ou até mesmo na formação de modelos) os resultados de um processamento.

segunda-feira, 13 de dezembro de 2010

[Arq e Org] Unidade de Controle


A Unidade de Controle juntamente com a Unidade Lógica e Aritmética (ALU) e registradores formam a CPU (Central Process Unit). Como dito em post anterior, a CPU é um dos componentes que constituem a estrutura básica de um computador. A Unidade de Controle é responsável por coordenar diversos elementos do processador.

Quatro registradores mais importantes da Unidade de Controle são:
  • PC (program couter): Mantém o registro da próxima instrução a ser buscada na memória.
  • IR (Instruction Register): Contém a última instrução buscada na memória.
  • MAR (Memory Address Register): Indica o endereço de memória para operações de leitura e escrita.
  • MBR (Memory Buffer Regiter): Contém o último valor lido da memória ou um valor a ser armazenado na memória.
Um ciclo de instrução pode ser dividido em quatro subciclos: busca, indireto, execução e interrupção, porém apenas a busca e execução estão presente em todos os ciclos de instrução, indireto e interrupção podem não ocorrer. Cada subciclo é composto por microoperações. Todas as microoperações caem em um dos seguintes tipos:
  • Transferencia de dados entre registradores.
  • Transferencia de dados de registrador para barramento.
  • Transferencia de dados de barramento para registrador.
  • Execução de operações de lógica e/ou aritmética utilizando os registradores como entrada/saída.
Sendo desta forma a Unidade de Controle desempenha funções de controle do sequenciamento e execução das microoperações.

terça-feira, 7 de dezembro de 2010

[Arq e Org] Conjunto de Instruções


Uma operação realizada pela CPU é determinada pelo conjunto de instruções que ela executa. As chamadas instruções de máquina. À coleção de instruções que uma CPU pode executar é chamada conjunto de instruções. Este conjunto de instruções é suficiente para traduzir programas escritos em uma linguagem de alto nível para a linguagem de máquina. Os elementos de uma instrução são:
  • Código da operação (opcode): Especifica a operação a ser executada;
  • Referência ao operando fonte: Indica as entradas para a operação;
  • Referência ao operando destino
  • Endereço da próxima instrução
Cada instrução é representada por um conjunto de bits. Devido às dificuldades de se trabalhar com bits, normalmente usam-se mnemônicos para representar as instruções, como por exemplo: ADD, SUB, LOAD, STORE. As instruções podem ser classificadas em grupos:
  • Processamento de dados (lógicas e aritméticas);
  • Armazenamento de dados;
  • Entrada/Saída;
  • Controle(teste e desvio).

[Arq e Org] Estrutura e funcionamento da CPU (Unidade Central de Processamento)


Diferentemente do que muitas pessoas imaginam, a unidade central de processamento (CPU) é o 'cérebro' do computador. a função da CPU é executar programas armazenados na memória buscando as instruções, examinando e executando-as uma após a outra. A CPU é composta por várias porções, são elas: Unidade de controle, Unidade lógica e aritmética e registradores. esses componentes da CPU são conectados entre si por barramentos. Barramentos podem ser entendidos como linhas de comunicação que permitem a interligação entre dispositivos internos ou externos.

A Unidade de controle é responsável por buscar as instruções na memória e determinar o seu tipo e pode ser pensada como uma máquina de estados finitos.

A unidade lógica e aritmética é responsável por executar operações como adição, e AND booleano, entre outras, para executar as instruções.

Os registradores presente na CPU são memórias pequenas e de alta velocidade para armazenar resultados temporários e controle de informações. Existem vários tipos de registradores de uso geral ou específico. O mais importante deles é o contador do programa (PC - Program Counter). Este contador indica a próxima instrução a ser buscada para execução. Outro de grande importância é o Registrador de instrução (Instruction Register), que contém a instrução executada no momento em questão.

A sequência de eventos ao longo de um ciclo de instrução é da sequinte forma: 1) Trazer a próxima instrução da memória para o registrador; 2) Alterar o contador de programa para indicar a próxima instrução; 3) Determinar o tipo de instrução trazida; 4) Se a instrução utilizar uma palavra na memória, determinar onde esta palavra está; 5) Trazer a palavra para dentro de um registrador na CPU, se precisar; 6) Executar a instrução; 7) Armazenar o resultado e voltar para a etapa 1 para iniciar a execução da instrução seguinte.

RISC Vs CISC

Reduced Instruction Set Computer ou Computador com Conjunto Reduzido de Instruções (RISC) é uma arquitetura de computadores que possui um pequeno número de instruções simples. Entre os processadores conhecidos que utilizam-se de arquitetura RISC incluem DEC Alpha, AMD 29k, ARC, ARM, Atmel AVR, MIPS, PA-RISC, Power (incluindo PowerPC), SuperH, e SPARC.

Complex Instruction Set Computer ou Computador com Conjunto de Instruções Complexo (CISC) é uma arquitetura de computadores que uma única instrução pode executar várias operações de baixo nível (como carregar da memória, operações aritméticas e guardar em memória). O termo foi criado em contraste ao RISC.

Muitos estudiosos afirmaram que mesmo que uma instrução RISC precisasse de 4 ou 5 instruções para fazer o que uma instrução CISC fazia com apenas uma, a arquitetura RISC ainda levaria vantagem por ser mais rápida. Porém diferente do que se imagina, os processadores modernos são mais CISC que RISC, pois contem um núcleo RISC que executa as instruções mais simples em um único ciclo de caminho de dados, enquanto interpreta as instruções mais complicadas no modo CISC tradicional.

Pipelining (Paralelismo)

A ideia principal do pipelining é trabalhar as diversas etapas do ciclo de instrução de forma paralela (contrariamente à forma serial executada antigamente) de forma a aumentar o desempenho da CPU.


A figura acima mostra um pipelining de 5 estágios. O estágio "S1" realiza a busca da instrução na memória e a coloca em um buffer até que ela seja necessária. O estágio "S2" decodifica a instrução, determina o seu tipo e de quais operandos ela necessita. O estágio "S3" localiza e busca os operandos, seja nos registradores, seja na memória. O estágio "S4" realiza o trabalho de executar a instrução. Finalmente o estágio "S5" escreve o resultado de volta no registrador adequado.

Na figura pode-se perceber que há realmente um paralelismo das etapas do ciclo de instrução. No tempo 1 apenas o estágio "S1" é feito na instrução 1, porém a partir do tempo 5 quando a instrução 1 está no estágio "S5" há simultaneamente a instrução 2, 3, 4 e 5 sendo trabalhadas em alguma etapa do ciclo de instrução.

No entanto podem existir conflitos de acesso à memória por parte dos estágios e nem todas as instruções possuem todos esses estágios, somado a isso a existência de instruções de desvio pode tornar a técnica de pipelining menos trivial. Para contornar esses problemas existem técnicas como:
  • Múltiplos Fluxos (duplicação de estágios iniciais);
  • Busca antecipada de instrução-alvo de desvio;
  • Memória de laço de repetição (loop buffer);
  • Previsão de desvio baseadas no opcode;
  • Previsão de desvio baseadas em histórico (BTB - Branch Target Buffer, ou BHT - Brach History Table).

[Arq e Org] Conceitos básicos


Arquitetura de computadores

Conceitos Básicos

Em ciência da computação, arquitetura de computadores é o design conceitual e estrutura operacional fundamental de um sistema de computador. É um desenho e descrição funcional dos requisitos e implementações de design para as várias partes de um computador, concentrando-se principalmente na maneira em que a Unidade Central de Processamento (CPU) trabalha internamente e acessa os endereço na memória.

Os computadores atuais são baseados no conceito introduzido por John von Neumann, a arquitetura de von Neumann. A arquitetura de Von Neumann é uma arquitetura de computador que se caracteriza pela possibilidade de uma máquina armazenar seus programas no mesmo espaço de memória que os dados, podendo assim manipular tais programas.

O ciclo de instruções de um programa é dividido nos estados: Cálculo do endereço de instrução; Busca da instrução (instruction fetch); Decodificação da instrução; Cálculo do endereço do operando; Busca do operando (operand fetch); Execução da instrução e Armazenamento do resultado. Nos computadores modernos é presente o conceito de interrupção de instrução para diminuir o tempo ocioso do processador, assim o ciclo de execução das instruções ganham alguns estados adicionais. Os tipos de interrupções mais comuns são interrupções de software, de clock e de Entrada/Saída e de falha de hardware.

A máquina proposta por Von Neumann reúne os seguintes componentes:
  1. Memória Principal
  2. Unidade Lógica e Aritmética
  3. Unidade de controle
  4. Equipamento de entrada e saída


Organização de computadores

Conceitos Básicos

Em ciência da computação, organização de computadores é a maneira que um conjunto de instruções (ISA - Instruction Set Architecture) é implementada em um processador. Um conjunto de instruções pode ser implementado com diferentes microarquiteturas. Implementações podem variar devido a diferentes objetivos de um certo design ou devido a mudanças na tecnologia.

Sendo assim, uma mesma arquitetura pode ser implementada por meio de diferentes organizações.

Para Tanenbaum (Organização Estruturada de computadores), organização é um modelo de abstração para facilitar o projeto e implementação de arquiteturas de computadores. Um computador é dividido em níveis ou camadas. Em cada nível, o computador pode ser programado utilizando a linguagem e os recursos daquele nível. Um nível pode ser visto como uma máquina virtual para execução de programas escritos no nível imediatamente superior. Como mostra a figura abaixo.

terça-feira, 27 de julho de 2010

[Java] Descrever programas para manipular suas próprias exceções


Na linguagem de programação Java, o programador pode definir suas próprias exceções. Exceções definidas pelo programador são criadas estendendo-se a classe Exception. As classes de exceções contêm os mesmos membros que a classe “normal” contém. Abaixo segue um exemplo de uma classe de exceção definida pelo programador que contém um construtor, algumas variáveis e métodos.
public class ServerTimedOutException extends Exception {
private int porta;

// Usa o método getMessage da classe Exception para retornar o motivo da exceção
public ServerTimedOutException(String m, int p) {
super(m);
this.porta = p;
}

public int getPorta() {
return porta;
}
}

Assim, para lançar essa exceção recém criada, use a seguinte forma:
throw new ServerTimedOutException("Não foi possível conectar ao servidor", 80);
Para demonstrar como utilizar esta nova exceção, veja o exemplo a seguir. Considere um programa cliente-servidor. Nele, se houver uma tentativa de conexão e o servidor não responder por mais de 5 segundos será lançada a exceção criada acima. Assim o exemplo ficaria da seguinte forma:
public void Conecta(Servidor nomeDoServidor) thows ServerTimedOutException {
private boolean conectou;
private int portaConectar = 80;

// abrir é um método fictício para tentar abrir uma conexão e retorna true com sucesso e false caso contrário.
Conectou = abrir(nomeDoServidor, portaConectar);

if(!conectou){
throw new ServerTimedOutException("Não foi possível conectar ao servidor", portaConectar);
}
}

E para capturar a exceção lançada pelo método Conecta:
public void ProcuraServidor() {
try{
Conecta(primeiroServidor);
}
catch(ServerTimedOutException e1){
System.out.printl(“Não foi possível conectar ao primeiro servidor. Tentando conectar ao outro servidor”);
//É possivel fazer try-catch aninhados. Veja abaixo
try{
Conecta(outroServidor);
}
catch(ServerTimedOutException eOutro){
System.out.printl(“Erro: ” + eOutro.getMessage + “ conectando na porta ” + eOutro.getPorta());
}
}
}

[Java] Identificar exceções comuns


A linguagem de programação Java fornece diversas exceções predefinidas. Algumas das exceções mais comuns são:



domingo, 25 de julho de 2010

[Java] Descrever as categorias de exceções


Hierarquia das exceções

Os objetos que herdam da classe Throwable incluem descendentes diretos e indiretos. A figura abaixo ilustra a hierarquia de classes da classe Throwable e suas subclasses mais significativas. A classe Throwable possui dois descendentes diretos: Error e Exception.


Classe Error

A classe Error e suas descendentes representam situações anormais que poderiam acontecer na JVM. Errors acontecem raramente e não devem ser capturados ou lançados por aplicativos.

Classe Exception

A classe Exception e suas descendentes representam situações não comuns que podem ocorrer durante a execução de um programa (Por exemplo, sinais IllegalAccessException indicam que um determinado método não pode ser encontrado, enquanto NegativeArraySizeException indica que um programa tentou criar uma matriz com um tamanho negativo) e podem ser capturadas pelo aplicativo. A maioria dos programas lança e captura objetos que derivam da classe Exception. Uma exceção indica que ocorreu um problema, mas não um problema grave do sistema. A maioria dos programas escritos irá lançar e capturar exceções ao contrário de erros. A subclasse de Exception, RuntimeException, é reservada para as exceções que indicam o uso incorreto de uma API.

Classe RuntimeException

RuntimeException indica um problema de design ou de implementação. Ou seja, ele indica as condições que nunca deve acontecer se o programa está funcionando adequadamente. Uma exceção ArrayIndexOutOfBoundsException, por exemplo, nunca deve ser acionada se os índices de array não estender além dos limites do vetor. Isto também se aplica, por exemplo, a referenciar uma variável de objeto nulo. Como um programa corretamente projetado e implementado nunca enfrenta este tipo de exceção, é de costume deixá-la sem tratamento. Isso resulta em uma mensagem em tempo de execução, e assegura que sejam tomadas medidas para corrigir o problema, ao invés de escondê-lo onde (você acha que) ninguém vai notar.

Exceções verificadas e não verificadas

As exceções em Java diferenciam em dois grupos de exceções: exceções verificadas e exceções não verificadas. As exceções verificadas são aquelas em que é obrigatório capturar ou declarar as exceções, enquanto as não verificadas não possuem a obrigatoriedade de capturar ou declarar as exceções. Se o requisito de capturar ou declarar uma exceção verificada não for satisfeito, o compilador irá retornar uma mensagem de erro informando que a exceção deve ser capturada ou declarada. O tipo de uma exceção é que define se é uma exceção verificada ou não verificada. Assim sendo, veja a figura abaixo (lembrando que nela possuem apenas as classes mais significativas). As subclasses das classes de cor vermelha são consideradas exceções verificadas, as demais são consideradas não verificadas.


Resumindo: Todas as classes que herdam de Exception e não herdam de RuntimeException serão verificadas enquanto todas as classes que herdam de RuntimeException, Error e suas descendentes serão não verificadas.

[Java] Uso das instruções try, catch e finally


O tratamento de exceções em Java ocorre transferindo a execução normal de um programa para o devido código de tratamento de exceções quando uma exceção ocorre. Para realizar o desvio da execução do programa utiliza-se as palavras chaves try, catch ou finally.

Instrução try

A sintaxe da instrução try se dá da seguinte forma:

try {
//código passível de exceções
}


Quando uma exceção é lançada em um bloco try o restante do código após à exceção é ignorado, transferindo o fluxo de execução para o tratamento dessa exceção.

Instrução catch

A instrução que captura (recebe) e trata da exceção lançada pela instrução try é a catch. Cada instrução try pode ter zero ou mais instruções catchs. A sintaxe de uma instrução catch é:

catch(<TipoDaExceção> <exceção>) {
//código de tratamento de exceção
}


Os blocos catchs devem ser posicionados logo após o término do bloco try, sem linhas de comando ou blocos entre eles. Assim como um bloco try e um catch devem ser dispostos juntos, dois blocos catchs também devem seguir este mesmo padrão. Deve-se atentar, porém, para a ordem dos blocos catchs. Blocos catchs devem ser dispostos de forma que primeiro estejam as exceções específicas e por último as gerais, pois quando uma exceção é lançada no bloco try, os blocos catchs são verificados um por um seguindo a sequencia das linhas do código. Assim se uma exceção específica for colocada após uma geral a específica nunca será executada.

Instrução finally

Apesar das instruções try e catch serem ótimas elas não são perfeitas. Quando uma exceção é lançada em uma instrução try, todo o restante do código é descartado e o fluxo é transferido para a instrução catch, assim se for necessário, por exemplo, de uma reinicialização de variáveis, ou desalocação de recursos. A instrução finally resolve este problema, pois será sempre excecutada após os comandos (a qualquer ponto) de um bloco try, lançando ou não uma exceção. A instrução finally é tão poderosa que até mesmo antes de um comando return do bloco try ela é executada. Desta forma, o bloco finally é o perfeito bloco para se fechar sockets, e realizar qualquer operação de limpeza que seu código necessite.

Comando try-catch-finally

Quando um bloco try é escrito, pelo um bloco catch ou finally deverá ser escrito. Como mostra a tabela abaixo:

try {}

-

-

INVÁLIDO

try {}

catch {}

-

VÁLIDO

try {}

finally {}

-

VÁLIDO

try{}

catch {}

finally{}

VÁLIDO

try{}

finally{}

catch {}

INVÁLIDO

catch {}

finally{}

-

INVÁLIDO

catch {}

-

-

INVÁLIDO

finally{}

catch {}

-

INVÁLIDO

finally{}

-

-

INVÁLIDO