sexta-feira, 29 de maio de 2015

Exceções - criando a sua própria e "repassando"

01 /**
02    Lancando uma excecao criada por mim mesmo.
03    Aproveitei para mostrar como "repassar a excecao".
04    Ela eh lancada em c(), repassada (por isso o throws)
05    e depois main repassa para a JVM (por isso o throws)
06    Note que se retirar o throws, usando a assinatura como
07    nos comentarios das linhas 13 e 17, ocorre erro de
08    compilacao.
09 */
10 
11 class MinhaExcecao {
12    public static void main (String[] argsthrows Exception {   
13    //public static void main (String[] args){
14       MinhaExcecao m=new MinhaExcecao();
15       m.c();
16    }
17    //void c() {
18    void c() throws Exception {
19       System.out.println ("lançando");
20       throw (new ExException());
21    }
22    // Esta eh otima: Java permite definir classes dentro de classes.
23    // Aqui usei apenas para mostrar que eh possivel.
24    class ExException extends Exception {
25       public String getMessage () {  // Sobrescreve getMessage
26          return toString();
27       }
28       public String toString (){   // Sobrescreve toString
29          return "ExException Rules!";
30       }
31    }
32 }
Java2html

quinta-feira, 28 de maio de 2015

Exceções - explicações

Java provê um mecanismo especifico para gerenciar eventos inesperados durante o ciclo de codificação e execução de programas. Neste mecanismo, a ocorrência desses eventos é transmitida através de objetos. A hierarquia de classes é apresentada abaixo:

Os objetos para gerenciar os eventos inesperados são Error e Exception. RunTimeException é subclasse de Exception. Todos são subclasse de Throwable (algo como Lançável). Nesta superclasse está implementada a maioria dos métodos.(https://docs.oracle.com/javase/8/docs/api/java/lang/RuntimeException.html)

As instâncias de Throwable, ou de suas subclasses, são lançadas pelo comando throw. Caso seja necessário marcar que determinado método lança exceções, sua assinatura é seguida pela declaração throws Exception. Exception requer essa marcação, ou seja, se um método lança (throw) uma instância de Exception então ele e todos os métodos que o invocam (numa sequência de chamadas) devem ou ser marcados (com isso eles repassam a exceção para o método que o invocou), ou tratar a exceção. O tratamento de uma exceção consiste em tentar executar o método que lança a exceção (para "tentar", coloca-se a invocação do método dentro de um bloco try), caso alguma exceção seja lançada, capturá-la (com o comando catch), tratá-la (num bloco de comandos associado ao comando catch) e fazer uma "limpeza" com o comando finally.

quarta-feira, 27 de maio de 2015

Exceção - código 9

01 /** Testando...
02 tratamento de exceção com todos os elementos (try catch finally).
03 O que motivou este teste Ã© verificar que elementos são executados mesmo
04 Qual a ordem de execução quando ocorre exceção e finally não tem return?
05 Neste código, o que vem depois do tratamento não Ã© executado por causa
06 do return dentro do try.
07 Este Ã© curioso - quando lança a exceção, executa o catch, antes do return salta para o finally, salta de volta para o finally e executa o return do catch.
08 Quando não lança, executa o finally e continua depois do try...
09 
10 Para que serve finally?
11 O bloco finally existe para agregar todas as instruções que "precisam ser executadas para encerrar o método limpamente". Em geral contém comandos que liberam recursos compartilhados, por exemplo, fecham arquivos, pipes, sockets, liberam acesso a variáveis compartilhadas, ... 
12 
13 um exemplo do que acontece quando isso não Ã© feito direito:
14 Quando estamos editando um arquivo armazenado num pendrive e o editor aborta com o arquivo aberto, em geral não Ã© possível ejetar o pendrive. Explicação: o funcionamento normal do SO não permite ejetar o pendrive enquanto o arquivo estiver em uso - isso evita perda de dados. Quando abrimos o arquivo no editor de texto, este informa ao sistema operacional que o arquivo está em uso. Quando o editor aborta, não informa ao sistema operacional para fechar (e liberar) o arquivo, logo para o SO, o arquivo continua em uso. O que vemos Ã© o editor fechado e o pendrive que não ejeta. 
15 */
16 public class DivZero6 {
17    public static void main (String[] args) {
18       int a, b;
19       a=5;
20       b=0;
21       try {
22          a=a/b;
23          System.out.println ("depois do erro, dentro do try.");
24       catch (Exception e) {
25          System.out.println ("catch " + e.getMessage());
26          return;
27       finally {
28          System.out.println ("finally");
29       }
30       System.out.println ("continuou...depois do try, fora do catch e do finally");
31    }
32 }
Java2html

Exceção - código 8

01 /** Testando...
02 tratamento de exceção com todos os elementos (try catch finally).
03 O que motivou este teste Ã© verificar que elementos são executados mesmo
04 Qual a ordem de execução quando ocorre exceção e finally não tem return?
05 Neste código, o que vem depois do tratamento não Ã© executado por causa
06 do return dentro do try.
07 */
08 public class DivZero5 {
09    public static void main (String[] args) {
10       int a, b;
11       a=5;
12       b=0;
13       try {
14          a=a/b;
15          System.out.println ("depois do erro.");
16          return;
17       catch (Exception e) {
18          System.out.println ("catch " + e.getMessage());
19          return;
20       finally {
21          System.out.println ("finally");
22       }
23       System.out.println ("continuou...");
24    }
25 }
Java2html

Exceção - código 7

01 /** Testando...
02 tratamento de exceção com todos os elementos (try catch finally).
03 O que motivou este teste Ã© verificar que elementos são executados mesmo
04 com return dentro dos tratamentos.
05 Obs. 1: a Exceção Ã© lançada (divisão por zero), capturada e tratada. Esperaria-se que programa encerrasse no return, entretanto o bloco finally Ã© executado.
06 */
07 public class DivZero4 {
08    public static void main (String[] args) {
09       int a, b;
10       a=5;
11       b=0;
12       try {
13          a=a/b;
14          System.out.println ("depois do erro.");
15          return;
16       catch (Exception e) {
17          System.out.println ("catch " + e.getMessage());
18          System.exit (0);
19       finally {
20          System.out.println ("finally");
21          return;
22       }
23       // neste codigo o que for posto aqui não será executado.
24    }
25 }
Java2html

Exceção - código 6

01 /** Testando...
02 tratamento de exceção com todos os elementos (try catch finally).
03 O que motivou este teste Ã© verificar que elementos são executados mesmo
04 com return dentro dos tratamentos.
05 Obs. 1: a Exceção Ã© lançada (divisão por zero), capturada e tratada. Esperaria-se que programa encerrasse no return, entretanto o bloco finally Ã© executado.
06 */
07 public class DivZero3 {
08    public static void main (String[] args) {
09       int a, b;
10       a=5;
11       b=0;
12       try {
13          a=a/b;
14          System.out.println ("depois do erro.");
15          return;
16       catch (Exception e) {
17          System.out.println ("catch " + e.getMessage());
18          return;
19       finally {
20          System.out.println ("finally");
21          return;
22       }
23       // neste codigo o que for posto aqui não será executado.
24    }
25 }
Java2html

Exceção - código 5

01 /** Causando...
02 
03 */
04 public class DivZero2 {
05    public static void main (String[] args) {
06       int a, b;
07       a=5;
08       b=0;
09       try {
10          a=a/b;
11          //return;
12       catch (Exception e) {
13          System.out.println ("catch " + e.getMessage());
14          return;
15       finally {
16          System.out.println ("finally");
17          return;
18       }
19       // System.out.println ("depois do tratamento..." + a);  // unreachable statement
20    }
21 }
Java2html

Exceção código 4

01 /** Causando...
02 ?? como ver qual o erro??
03 ... capturando ...
04 ... Ã© possível capturar um erro!!!!
05 */
06 public class StackEater2 {
07    public static void main (String[] args) {
08       int a=0, b=0;
09       c(a,b);
10    }
11    static void (int a, int b) {
12       System.out.println ("x");
13       try {
14          c(a,b);
15       catch (Error e) {
16          System.out.println (e.getMessage());
17          System.out.println (e.toString());
18       }
19    }
20 }
Java2html

Exceção - código 3

01 /** Causando...
02 ?? como ver qual o erro??
03 java StackEater 2> err.txt
04 
05 */
06 public class StackEater {
07    public static void main (String[] args) {
08       int a=0, b=0;
09       c(a,b);
10    }
11    static void (int a, int b) {
12       System.out.println ("x");
13       c(a,b);
14    }
15 }
Java2html

Exceção - código 2

01 /** Causando...
02 ?? como ver qual o erro??
03 java StackEater 2> err.txt
04 
05 */
06 public class StackEater {
07    public static void main (String[] args) {
08       int a=0, b=0;
09       c(a,b);
10    }
11    static void (int a, int b) {
12       System.out.println ("x");
13       c(a,b);
14    }
15 }
Java2html

Exceção código 1

01 /** Causando...
02 
03 */
04 public class DivZero {
05    public static void main (String[] args) {
06       int a, b;
07       a=5;
08       b=0;
09       a=a/b;
10       System.out.println (a);
11    }
12 }
Java2html

Array na memória

1 class TestaArray {
2    public static void main (String[] args){
3       int[] arr;
4       arr= new int[10];
5       arr[5]=5;
6    }
7 }
Java2html




Sobre memória

O hardware e instruções para gerenciamento de memória em processadores Intel Core pode ser visto no capítulo 3 do manual do processador:
http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.html

A forma como a memória física é usada por Windows e por Linux pode ser vista em:
http://blog.codinghorror.com/dude-wheres-my-4-gigabytes-of-ram/
http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map/
(não encontrei referências no site da Microsoft ou do Linux... a maioria das referências que visitei concordam com as apresentadas)

Agora aumenta a importância do post para nós:

O sistema operacional gerencia a memória física (inclui RAM, HD, swap,...) e quando carrega o executável em memória para que seja executado, expõe aos programas um mapeamento da memória física (que é o espaço de endereçamento virtual):

http://stackoverflow.com/questions/2048007/linux-ia-32-memory-model
http://www.linuxjournal.com/article/4681
http://www.linuxjournal.com/article/6701?page=0,0
http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/

Em especial o exemplo relativo a figura abaixo é bastante ilustrativo do que explico sobre onde (no espaço de endereçamento virtual) ficam armazenados o programa, os literais e as variáveis (estáticas, tipos primitivos e objetos (tipos abstratos)) em aula.

http://static.duartes.org/img/blogPosts/mappingBinaryImage.png

Agora é totalmente nosso território!!!:

Em especial, quando criamos arrays com new e com referência atribuída a uma variável estática, a variável fica no "segmento" de dados e os elementos do array fica no heap.

No escopo de ACH2001 o interesse maior é com a alocação de variáveis (objetos) em memória, geralmente sem preocupação sobre sua localização exata ("segmento" de código, de dados, pilha (stack), heap,...). É suficiente considerar a memória um espaço de armazenamento com endereços.

Relembrando (o pouco que) sabemos sobre compiladores, os identificadores são necessários para facilitar o trabalho do programador. Compiladores substituem identificadores por (algum tipo de) endereço de memória, é suficiente para o programa operar corretamente. Assim, em representações de memória, o identificador é colocado como um rótulo dado a uma posição de memória.