A Linguagem Java Um Curso Orientado a Objetos Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 1 Características de Java Linguagem totalmente Orientada a Objetos Portabilidade Alta Performance Facilidades para Processamento Distribuído Ambiente Seguro Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 2 Compile-Time Source Code Compiler Run-Time Class Loader Interpreter Bytecodes JAVA Virtual Machine Byte Code Verifier Run-Time Classes Security Manager Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 3 Java Virtual Machine (“browsers” que entendem JAVA) JAVA files Class byte code files PC hardware CPP files .exe program Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 4 Tudo em Java é objeto Exceção (parcial): os tipos de dados primitivos. Estes tipos são padronizados para todas as plataformas. São eles: Data Type byte short int long float double char Size 8-bit 16-bit 32-bit 64-bit 32-bit floating point 64-bit floating point 16-bit Unicode Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 5 Literais (i) São usados para representar os tipos de dados primitivos. Iniciando com: – 0 ---> octais – 0x ou 0X ---> hexadecimais – literais maiores que 0x7FFFFFFF (2.147.483.647) são automaticamente assumidos como long. Qualquer literal inteiro seguido de l ou L é um long. floating-point: contêm expoente ou ponto decimal. Podem ser float ou double. Por default são do tipo double. Ex.: 6.2832, 0.1, 10E-13, 2.5 E12 (double) Float: 45.34F, 0.1F, 2.7987F, 11.3E-23F. Double:23.52D, 1..88E-3D. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 6 Literais (ii) Booleans: Podem assumir um dos dois valores (constantes) true ou false. Não pode haver cast para inteiros. Character: são representados por um único caracter entre aspas. Ex.: ‘a’, ‘ ‘. Um character pode também ser definido por : ‘\xNN’, onde NN é o valor UNICODE do caracter. Seqüências de escape são usadas para representar caracteres especiais e são precedidas por uma barra invertida (\). Ex.: \n new line \t tab \r carriage return \b backspace Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 7 Variáveis (i) Em JAVA há três tipos de variáveis: instance, class e local. Local: são variáveis declaradas dentro de métodos ou blocos. Forma geral: <type> <variable name> double pi; int count; public GetHalf () { int half; // variável local half = FirstVariable / 2; return half; } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 8 Variáveis (ii) Instance: São definidas para uma instância de um objeto. Class FirstClass { int FirstVariable = 0; //inicializa com zero //Atribui valor à variável public void SetValue (int NewValue) { FirstVariable = NewValue; } // Obtém o valor da variável public int GetValue ( ) { return FirstVariable; } } No caso, FirstVariable é uma variável tipo instance. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 9 Variáveis (iii) Variáveis class são empregadas para definir dados que são associados à classe e, não aos objetos instanciados. São declaradas usando-se a keyword static Class BankAccount { // inicialização dos números das contas static private int m_nNextAccountNumber = 1001; // declaração de outros membros ... // declaração de outros métodos ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 10 Precedência dos Operadores . [] () ++ -- ! ~ instanceof * / % + << >> >>> < > <= >= = = != Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. & ^ | && (short circuit evaluation) || (short circuit evaluation) ?: = op= , 11 JAVA Keywords JAVA byte boolean try catch finally throw private public protected transient synchronized if else for while do native final finally short long extern switch case default threadsafe abstract auto register break continue import class extends return static volatile sizeof const instanceof implements typedef interface package null new true false this super char struct union int short long C enum float double signed unsigned Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 12 Fluxo de Controle (i) if statement for loop while loop switch statement Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 13 Fluxo de Controle (ii) if statement if (boolean expression) { //... qualquer número de comandos } else { //... qualquer número de comandos } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 14 Fluxo de Controle (iii) while loop while (boolean expression) { //... qualquer número de comandos } do { //... qualquer número de comandos } while (boolean expression); Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 15 Fluxo de Controle (iv) for loop for (expr1; expr2; expr3) { //...qualquer número de comandos } Equivalente a: avalia expr1; //inicialização do loop while (expr2) { //... Qualquer número de comandos avalia expr3 // expressão para controlar o loop } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 16 Fluxo de Controle (v) switch statement switch (expr) { case cexpr1: // comandos JAVA break; case cexpr2: // comandos JAVA break; ... case cexprn: // comandos JAVA break; default: // mais comandos JAVA } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 17 Arrays (i) Não se pode declarar um array com um tamanho pré-definido. Deve ser declarado como uma variável não inicializada. Podem ser usados para classes e tipos primitivos de dados int String String[] numbers[]; //para arrays de inteiros myStrings []; // para arrays de objetos do tipo string myStrings; //forma alternativa O próximo passo é criar o array através do uso do operador new. Constrói-se uma instância do objeto. int numbers[] = new int[5]; //array de inteiros, de dimensão 5. String myStrings[] = new Strings[20] ; //array de Objetos String, de dimensão 20. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 18 Arrays (ii) Os slots ainda nada contêm. Todavia são inicializados com valores default (inteiros: 0; objetos String: null). Finalmente atribuem-se valores aos elementos do array. myStrings[0] = “My first String”; myStrings[1] = “My second String”; numbers[0] = 20; IndexOutOfBoundException (índice inválido) Uma variável instância pública chamada length é usada para se obter o tamanho do array. Int q = numbers.length; // q = 5 Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 19 Arrays (iii) JAVA não suporta arrays multidimensionais Podem ser simulados através de arrays de arrays int k[][] = new int[5][4]; k[1][3] = 100; //atribui valor a um dos elementos do array Outra forma de se criar um array: int z[][]; int outerSize = 5; int innerSize = 4; z = new int[outerSize][innerSize]; Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 20 class TestArray { public static void main (String args[]) { int z[][]; int outerSize = 5; int innerSize = 4; z = new int[outerSize][innerSize]; int i, j , k; // linha --> i; coluna --> j for (i = 0, k = 0; i < innerSize; i++) for (j = 0; j < outerSize; j++) { z[j][i] = k++; System.out.println("i = " + i + " j = " + j + " " + z[j][i]); } int w[][] = new int[10][]; w[0] = new int[5]; w[3] = new int[3]; System.out.println (w.length + " " + w[0].length + " "+ w[3].length); w[10] = new int[3]; // OutOfBoundException /* int y[][] = new int [10][]; y[0][] = new int [5]; y[][2] = new int [10]; */ } // missing array dimension // missing array index } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 21 Estrutura de um Programa em JAVA Um progama em JAVA é composto de classes Apenas uma classe implementa o método main(). As classes em JAVA podem estar em múltiplos arquivos (compilation units) cada arquivo fonte termina com o sufixo .java Cada classe contém data members (declarações de tipos de dados) e methods (funções que operam nos data members da classe) O conjunto de classes em uma unidade de compilação podem fazer parte de um mesmo package. Isto significa que todas as classes serão pré-fixadas com o nome do package. O comando import instrui o compilador para carregar uma determinada classe que está em uma outra unidade de compilação. O comando interface especifica um conjunto de métodos que descrevem, em alto nível, um comportamento determinado. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 22 Estrutura de um Programa em JAVA package mystech.util; /* OPTIONAL - these classes may belong to a package */ import java.util.Vector; /* OPTIONAL - import other classes for use in this class */ interface InputOutput { /* OPTIONAL - an interface is a group of methods */ void read(); void write(); } /* OPTIONAL - multiple classes per file */ class aCLass { ... } ... class mainClass { public static void main(String args[]) { ... } } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 23 Executando um Programa em JAVA Para compilar um programa em bytes codes independentes de arquitetura: javac <filename> filename é um arquivo .java O compilador gera um arquivo <classname>.class para cada classe. Cada arquivo contém os byte-codes para a classe correspondente . O interpretador JAVA executa os byte-codes java <classname> Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 24 Standalone Application public class App1_1 { public static void main(String args[]) { System.out.println("Hello, world"); } } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 25 Applets public class HelloMan extends Applet { public void paint(Graphics g) { g.drawString("Hello, world", 0, 20); } } <HTML> <HEAD> <TITLE>Hello World</TITLE> </HEAD> <BODY> <APPLET CODE="HelloMan.class" WIDTH=250 HEIGHT=100> </APPLET> </BODY> </HTML> Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 26 import java.applet.Applet; import java.awt.*; Objetos e Classes em JAVA (i) Classes são os templates para especificar o estado e comportamento de um objeto em tempo de execução. Objeto é uma instância de uma classe. Classes consistem de data members (instance variables) e métodos. Após a definição de uma classe, pode-se criar os objetos correspondentes através do operador new. O operador new – aloca memória para o objeto – inicializa variáveis de instância – chama um construtor Construtores: são métodos que são chamados quando o objeto é instanciado. Provêem inicializações adicionais para o objeto. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 27 Objetos e Classes em JAVA (ii) Métodos: especificam o comportamento dos objetos Os métodos possuem duas partes: definição e corpo. Definição: Possui três componentes (signature): – valor retornado – o nome do método – uma lista de parâmetros Corpo: algoritmo que opera sobre os data members. Os métodos podem declarar variáveis locais. Os métodos podem ser sobrecarregados (em particular, os construtores) - Overloading - Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 28 Exemplos de classes em JAVA Conta Bancária Learn Java Now . Stephen R. Davis. Microsoft Press. Pág. 41. Chap03/BankAccount/BankAccount.java Livros e Estantes Java for C/C++ Programmers. Michael C. Daconta. John Wiley & Sons, Inc. Pág. 15 e 17. SRC1-4.java e SRC1-5.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 29 Exemplos de programas em JAVA Uso da classe Conta Bancária Learn Java Now . Stephen R. Davis. Microsoft Press. Pág. 43. Chap03/BankAccount/App1_3.java Livros e Estantes Java for C/C++ Programmers. Michael C. Daconta. John Wiley & Sons, Inc. Pág. 18 e 20. SRC1-6.java SRC1-7.java (versão com GUI) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 30 Method Signature Os métodos possuem duas partes: definição e corpo. A definição deve possuir pelo menos três partes: – valor retornado – nome – lista de parâmetros A signature de um método compreende o valor retornado pelo método, o nome do método e a sua lista de parâmetros. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 31 Overloading Methods (i) Métodos com o mesmo nome para diferentes classes Solução: qualificar o nome por completo. void fn(TV my tv, Radio myradio) { mytv.ChangeChannel(); //troca o canal da tv myradio.ChangeChannel(); //troca a estação do radio } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 32 Overloading Methods (ii) Quando o método é chamado de dentro da classe não é necessária a qualificação completa class TV { void ChangeChannel() { //código do método ... } void SomeFunction() { ChangeChannel(); } } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 33 Overloading Methods (iii) Métodos com o mesmo nome para a mesma classe Solução: a distinção entre os métodos é feita através dos argumentos class BankAccount { double m_dCurrentInterestRate; // the Account’s interest rate // Rate - inquire or set interest rate double Rate() { return m_dCurrentInterestRate; } double Rate(double dNewRate) { if (dNewRate > 0.0 && dNewRate < 20.0) { m_dCurrentInterestRate = dNewRate; } } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 34 Overloading Methods (iv) ... BankAccount baMyAccount ... baMyAccount.Rate (0.8); // estabelece a taxa baMyAccount.Rate (): // recupera a taxa corrente ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 35 Overloading Methods (v) Observação: Não é possível diferenciar dois métodos apenas em função do valor retornado. class RealNumber { // convert current RealImaginary number to a double double Convert (); //convert current RealImaginary number to a int int Convert (); } // Dá origem ao seguinte problema: void Fn(RealNumber rn) { rn.Convert (); // qual dos Convert devo usar??? } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 36 Overloading Constructors Ver o exemplo JustJavaBook/examples/ch2/test2c.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 37 Herança Ver o exemplo JavaNow/chap07/BankAccount/BankAccount.java /App1_7.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 38 Polimorfismo Ver o exemplo JustJavaBook/example/ch2/test2e.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 39 Garbage Collector Além do gerenciamento de objetos em memória o Java run-tyme system mantém um registro de todas as referências aos objetos. Quando um objeto não é mais referenciado ele é automaticamente removido da memória. O programador é liberado da tarefa (error prone) de retornar ao espaço disponível os objetos que foram previamente alocados. O Garbage Collector é executado como um thread de baixa prioridade nos momentos em que a máquina encontra-se inativa. A área de memória ocupada pelos objetos não é necessariamente liberada de imediato. O Garbage Collector pode ser explicitamente chamado: System.gc ( ); // jamais faça isso em loops. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 40 Membros Estáticos Class Members: são propriedades que são compartilhadas por todos objetos de uma mesma classe. São também chamados de membros estáticos class Bank Account; { // a taxa de juros é para ser compartilhada por todas as contas // bancárias. static double m_dCurrentInterestRate; ... } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 41 Métodos Estáticos São métodos que são compartilhados por todos os objetos de uma classe. Não possuem a referência this. Os métodos estáticos são invocados usando-se o nome da classe. Exemplos: Learn Java Now . Stephen R. Davis. Microsoft Press. Pág. 62 e 64. Chap04/BankAccount/BankAccount.java Chap04/BankAccount/App1_4.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 42 Modificadores de Acesso Controlam o nível de visibilidade que os métodos e data members de uma classe terão para as outras classes. Public: indica que se pode ter acesso ao método ou data member assim declarado em uma dada classe X, a partir de qualquer classe ou método que tenha visibilidade da classe X. Protected: o acesso é restrito apenas às subclasses da classe protected. Private: o método ou data member não está disponível para qualquer outra classe, exceto para aquela onde ele aparece. Package (friendship ?): é o acesso default. Nào corresponde diretamente a uma keyword de acesso. Quando se cria um package (biblioteca de classes), se não se especifica um modificador de acesso para um dado método ou dm, todas as outras classes do package poderão ter acesso ao mesmo. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 43 Java Standard Library Compreende os packages: lang util io net awt applet Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 44 Lang Package Compreende as classes que formam o núcleo da linguagem Java. Type Wrappers: Number, Character, Boolean, Double, Long, Float, Integer Superclasses Abstratas: Class, Object Strings: String, StringBuffer System Information: System, Process, Runtime, ClassLoader, SecurityManager Funções Matemáticas: Math Threads: Thread, Thread Group Run Time Errors: StackOverFlowError, OutOfMemoryError... Exceções: ClassNotFoundException, Throwable ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 45 Util package Compreendem objetos utilitários que ajudam aos programas manipular e armazenar outros objetos eficientemente. Containers: HashtableEntry, Properties, Vector, VectorEnumerator, Stack, ObserverList, BitSet, Dictionary Miscelaneous: Random, Date, StringTokenizer, NoSuchElementException. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 46 IO package Comprende classes que oferecem facilidades para input e output. InputStreams (analogia com fluxo contínuo, permitindo redirecionamento de dados): InputStream, ByteArrayInputStream, FilterInputstream, PushbackInputStream, StringBufferInputStream, DataInputStream, BufferedInputStream, LineNumberInputStream, SequenceInputStream, PipedInputStream, StreamTokenizer. OutputStreams: OutputStream, DataOutputStream, BufferedOutputStream, PrintStream, FilterOutputStream, ByteArrayOutputStream,PipedOutputStream. Files (estas classes compreendem os armazéns de dados - ou data pools - que os streams usam para destino ou origem dos dados): File, File FileImputStream, FileOutputStream, RandomAccessFile Exceções: IOException, InterruptedIOException,FileNotFoundException, EOFException, UTFDataFormatException. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 47 Net package Consiste de classes para comunicar com outros computadores (via sockets) e com servidores internet (http, ftp, etc...). WebTools (conjunto de classes para conectar e processar URLs - Uniform Resource Locators): InetAddress, URL, URLConnection, URLStreamHandler, ContentHandler. Sockets (Um socket é um modo simples de conectar processos em diferentes máquinas, via uma rede TCP/IP, e compartilhar dados. É similar a um network pipe) Escreve-se e lê de/para um socket da mesma forma que em um arquivo): ServerSocket, Socket, SocketImpl, SocketInputStream, SocketOutputStream. Exceções: ProtocolException, SocketException, UnknowHostException, UnknowServiceException, MalformedURLException. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 48 AWT package Conjunto de classes para implementar o Abstract Windows Toolkit, o qual implementa uma graphical user interface (GUI) neutra relativamente às diversas plataformas. O AWT fornece classes para janelas, botões, listas, menus, layout de objetos em containers, etc... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 49 Applet package Conjunto de classes para a criação de applets. Um applet é uma pequena aplicação Java que pode ser “inserida” em uma página WEB e pode ser executada por um browser (ex.: HotJava, Netscape, etc...). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 50 Lang Package: a classe Object (i) Object: é a classe base de todas as outras classes em Java. Os métodos da classe object estão presentes em todas as classes. Pode-se, evidentemente, fazer um override destes métodos. Alguns métodos interessantes da classe Object: Cada objeto possui uma representação em String. Pode ser um nome gerado pelo sistema ou, pela classe. P. ex., a representação de um objeto do tipo String é o próprio string. Como obtê-la: Object o = new Object (); System.out.println (“Object = “+ o); // i) System.out.println (“Object = “+ o.toString()); // ii) // i) e ii) são funcionalmente equivalentes. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 51 Lang Package: a classe Object (ii) O método toString é automaticamente chamado, quando o objeto faz parte de um println. Deve-se providenciar um override para o método toString caso se deseje uma representação customizada para os objetos de uma dada classe. Isto é feito para a biblioteca de classes de Java. Em Java as classes não possuem um método destructor. Em Java o gerenciamento de memória é automático … Há, todavia o método finalize () imediatamente antes do gc (). Deve-se providenciar um override para este método, no caso de se desejar algumas tarefas específicas tais como: fechar arquivos, desfazer uma conexão, etc… finalize() deve ser usado com cuidado pois não se sabe exatamente quando é realizada a garbage collection. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 52 Lang Package: a classe Class Cada classe em Java possui um descriptor. A classe Class representa este descriptor, ao qual pode-se ter acesso através do método getClass () da classe Object. Não se pode alterar este descriptor, apenas utilizá-lo para se obter informações úteis. P. ex., o método getSuperclass () retorna o descritor de classe da superclasse de uma dada classe. String s = “My name is …”; System.out.println (“String superclass = “ + s.getClass().getSuperclass()); O método getName() retorna o nome da classe. métodos wait (), notify e notifyall () // relacionados com threads... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 53 Lang Package: Class String (i) Literais strings são implementados como objetos da classe String. String s1 = “A string”; String s2 = s1 + “with some aditional text”; Como strings são objetos só se pode operar nos mesmos através de métodos apropriados, i.e., não se pode alterá-los após criados. substring(): retorna um string começando em um índice dado. length(): retorna o comprimento do string. System.out.println(s2.substring(s1.length())); Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 54 Lang Package: Class String (ii) valueOf(): vários métodos (overloaded) que recebem como parâmetro um tipo de dado primitivo e retornam uma representação em string. Este trecho de código faz a variável string s ter o valor “100”. int i = 100; String s = String.valueOf(i); // note que neste exemplo não usamos //uma instância da classe String para invocar o método valueof(). //valueof() é um método de classe ou método estático. Equals(): retorna um booleano indicando se dois objetos string possuem strings internos idênticos. if (s2.equals(s1)) { ... } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 55 Lang Package: Class StringBuffer (i) Trata-se de um outro tipo de classe string, mas que pode ser modificada. Em qualquer ponto no tempo, um objeto StringBuffer contém uma seqüência de caracteres particular, mas o comprimento e o conteúdo da seqüência podem ser alterados através da invocação de certos métodos. Um StringBuffer tem uma capacidade. Enquanto ela não for excedida não será necessário criar um novo buffer (array) interno. StringBuffers podem ser usados por múltiplos threads. Os métodos são sincronizados, quando necessário, de modo a preservar a consistência do StringBuffer. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 56 Lang Package: Class StringBuffer (ii) Exemplo de uso do método append (): ... String s2 = “A new type of string” StringBuffer sb = new StringBuffer (s2); sb.append (‘.’); System.out.println (sb); ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 57 Lang Package: Type Wrapper Classes (i) Type Wrapper Classes Boolean Character Double Float Integer Long ---------------------------------Number Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. Tipos de Dados Primitivos boolean char double float integer long -----------------------------------Superclass que define métodos para os type wrappers numéricos 58 Lang Package: Type Wrapper Classes (ii) Para criar instâncias da classe Integer: Integer I1= new Integer(6); Integer I2 = new Integer(“8”); Para converter um valor interno para um novo tipo de dados: double db = I2.doubleValue(); Existem uma série de métodos estáticos para realizar operações em tipos de dados primitivos (sem criar uma instância de uma classe). int i = Integer.parseInt(“7”); Se o string não puder ser convertido para um número, um objeto NumberFormatException é lançado (thrown). Existem variáveis públicas que dão informações sobre os limites superior e inferior para os diversos tipos de dados. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 59 Lang Package: Type Wrapper Classes (iii) Exemplo de uso de classes Type Wrapper MichaelCDaconta/Javasrc/SRC4-1.java Mostra: i) como converter strings em números via os métodos valueOf() ou parseInt(); ii) Como converter tipos de dados primitivos em objetos, para uso em outras classes Java (ex., a class Vector). Isto é essencial quando se usa classes containers (util package). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 60 Lang Package: System Information (i) Categoria de classes que provêem informações sobre o sistema operacional e acesso a alguns serviços do sistema operacional. System: provê um método independente dos sistema, para se ter acesso à funcionalidade e informações do sistema. (ver o exemplo: MichaelCDaconta/Javasrc/SRC4-5.java) Process: classe instanciada a partir de uma chamada ao método exec() da classe Runtime. A chamada a exec() é muito comum em sistemas UNIX, aonde é usada para originar um novo processo. A classe Process provê métodos para obter o stdin e stdout do processo, matar (kill) o processo e obter o exit value se o processo terminou. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 61 Lang Package: System Information (ii) Runtime: é uma classe adjunta a System. (exemplo: MichaelCDaconta/Javasrc/SRC4-6.java) SecurityManager: é uma classe abstrata que possibilita que uma política de segurança seja criada e tornada obrigatória em seu código JAVA. Possui métodos que permitem checks ao ClassLoader, à criação de arquivos, o acesso de applets a packages, etc... ClassLoader: classe abstrata que pode ser estendida para permitir a carga de classes ou de um arquivo ou, da rede. Este mecanismo permitirá uma verdadeira distribuição dinâmica de objetos para qualquer máquina na rede, que disponha de um JAVA run time. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 62 Lang Package: classe Math Disponibiliza uma série de funções matemáticas (exemplo: MichaelCDaconta/Javasrc/SRC4-7.java) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 63 Lang Package: classes Thread As classes Threads implementam múltiplos contextos de execução baseados em prioridades, em um único programa. Thread: Deve-se criar uma subclasse desta classe para se produzir um thread. Deve-se fazer o override do método run() da classe Thread com o código que se deseja ser executado. ThreadGroup: Permite que se agrupe threads para melhor manipulá-los. Pode-se, p. ex, alterar as prioridades de todos os threads de um mesmo grupo... (exemplo: MichaelCDaconta/Javasrc/SRC4-8.java) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 64 Exception Handling (i) Um dos grandes desafios para os programadores sempre foi o de como manipular erros em tempo de execução de modo elegante e eficiente. Na programação tradicional usava-se o comando return para se passar um código indicando erro ou sucesso. O código ficava sobrecarregado com uma série de if ...else em torno de cada chamada à função. Freqüentemente os programadores ignoravam o código de retorno e omitiam o código necessário ao tratamento dos erros, levando o programa a terminar de maneira abrupta e inesperada. A causa dos erros não se tornava logo visível. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 65 Exception Handling em JAVA (ii) Um exception handler é freqüentemente chamado de um bloco try-catch. No bloco try encontra-se o código a ser executado e que corresponde ao curso de ação normal. Se ocorrer um erro, Java ou o método chamado podem gerar um objeto (exception object) para indicar o problema. O exception object é passado ao run-time system em busca de um modo para tratar (handle) o erro. O ato de passar o exception object para o run-time system é chamado throwing an exception. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 66 Exception Handling em JAVA (iii) Exceções são , de algum modo, similares a eventos. Java pára a execução no local em que ocorreu a exceção. O exception object é então criado e lançado (thrown) pela correspondente sessão de código. Como com eventos, a exceção deve ter algum trecho do código apto a tratá-la. Esta sessão do código que recebe o exception object captura (catch) a exceção. Um exception handler possui um bloco opcional colocado ao final do bloco try-catch chamado finally block. O finally block provê um código para ser executado independente da ocorrência ou não da exceção. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 67 Exception Handling em JAVA (iv) Exceptions são representadas por objetos que são instâncias da classe java.lang.Exception. Várias subclasses de Exception fornecem informação especializada (e eventualmente comportamento) para diferentes tipos de problemas. Um comando try pode possuir várias cláusulas catch para especificar diferentes tipos de exceções. Ex.: try { readFromFile(“foo”); ...} catch (FileNotFoundException e) {...} // handle file not found catch (IOException e) { ...} // handle read exception catch (Exception e) {...} // handle all other exceptions Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 68 Exception Handling em JAVA (v) O programador pode lançar (thrown) suas próprias exceções em Java: uma instância da classe Exception, ou de uma de suas prédefinidas subclasses, ou ainda criar suas próprias subclasses mais especializadas (todas são subclasses da classe Throwable). À keyword thrown segue-se a alocação de um objeto (Exception) do heap. O construtor de Exception aceita um objeto String, que poderá conter uma descrição resumida do problema. O método Exception.printStackTrace identifica aonde a exception foi lançada (thrown), seguindo-se aonde o método X causador da exception foi chamado, o método que chamou X e assim por diante... As exceptions são propagadas ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 69 Exception Handling em JAVA (vi) Exemplos: i) JavaNow/Chap09/ComplexNumbers.java JavaNow/Chap09/Myclass.java ii) JavaNow/Chap09/BankAccount/InsufficientFundsException.java JavaNow/Chap09/BankAccount/BankAccount.java JavaNow/Chap09/BankAccount/test.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 70 Java Exceptions Exception (super classe) InterruptedException ClassNotFoundException NoSuchMethodException RuntimeException (JVM) ArithmeticException ClassCastException ArrayStoreException NullPointerException Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. NegativeArraySizeException IllegalArgumentException IllegalThreadStateException NumberFormatException (capturar sempre) IndexOutOfBoundsException ArrayIndexOutOfBoundsException StringIndexOutOfBoundsException Security Exception 71 Exception Handling em JAVA (vii) Ver a relação de exceções em: Exploring Java, Patrick Nyemeier e Joshua Peck, cap.IV, pg 96, fig 4.1 Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 72 Lang Package: Run Time Errors Uma série de classes extende a classe Error, que por sua vez extende a classe Throwable, e os objetos correspondentes são lançados (thrown) pelo Java run time quando ocorre uma condição anormal. Em geral não precisam ser tratadas pelo seu programa. ThreadDeath: é lançada quando o método thread.stop() é invocado. (Não deve ser capturada). VirtualMachineError: sinaliza que a MVJ esgotou os seus recursos ou um erro interni irrecuperavel. StackOverflowError: indica que o stack da MVJ sofreu overflow. (exemplo: MichaelCDaconta/Javasrc/SRC4-9.java) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 73 Lang Package: Run Time Errors (i) OutOfMemoryError: extende VirtualMachineError. Indica que a MVJ não pode atender a um pedido de memória. (exemplo: MichaelCDaconta/Javasrc/SRC4-10.java) UnknownError: extende VirtualMachineError. A princípio nunca deveria ocorrer. LinkageError: estende Erro. Indica que uma classe é dependente de uma outra classe. Todavia, esta última alterou-se de forma incompatível, depois da compilação da primeira classe (ver explicações na pág. 168 do livro do Daconta). NoClassDefFoundError: Estende LinkageError. A MVJ não consegue encontrar uma classe (isto pode ocorrer se a classe existia em tempo de compilação, porém, depois, foi removida). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 74 Lang Package: Run Time Errors (ii) ClassCircularityError: estende LinkageError. Uma circularidade foi detectada durante a inicialização da classe (A -->B -->A). ClassFormatError: estende LinkageError. Indica a detecção de um formato de arquivo inválido, no momento em tentava carregar uma classe. VerifiyError: estende LinkageError. Ocorreu uma verificação ao se tentar carregar uma classe. UnsatisfiedLinkError: estende LinkageError. Esta classe é lançada se um método nativo foi declarado nativ, mas o run time não pode encontrar a dynamic library para linkar, ou houve o link porém o método não faz parte daquela library. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 75 Lang Package: Run Time Errors (iii) IncompatibleClassChangeError NoSuchMethodError NoSuchFieldError AbstractMethodError IllegalAccessError InstantiationError Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 76 Interface Conjunto de métodos que especificam o protocolo (comportamento) que uma ou mais classes devem implementar. O conceito de Interface é utilizado em JAVA para implementar características típicas de Herança Múltipla. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 77 Util Package: Containers (i) Conjunto de classes para armazenamento e recuperação efeciente de outros objetos. Todos os containers podem armazenar qualquer objeto JAVA. Os objetos armazenados não precisam ser todos homogêneos. Pode-se usar run time type information para determinar o tipo on the fly. Dictionary: Classe abstrata que descreve um conjunto associativo (associa chaves a valores). Super classe de HashTable. HashTable: classe para acesso randômico que usa uma função hash ( o método HashCode()). Há a possibilidade de colisões. (exemplo: MichaelCDaconta/Javasrc/SRC4-17.java) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 78 Util Package: Containers (ii) Properties: extende HashTable. Cria objetos HashTable persistentes que podem ser salvos em um stream e, carregados de um stream. Vector: Arrays que podem crescer, i.e., a dimensão não é fixa. (exemplo: MichaelCDaconta/Javasrc/SRC1-7.java) Enumeration: Interface que descreve o protocolo para percorrer os elementos de um conjunto. Possui dois métodos: hasMoreElements() e nextElement(). VectorEnumerator: Classe final (não pode ser extendida) que implementa a interface Enumeration. Stack: Extende Vector. Implementa o conceito de pilhas. (exemplo: MichaelCDaconta/Javasrc/SRC4-16.java) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 79 Util Package: Containers (iii) Observer: Uma interface que possibilita à classe ser observada por uma instância da classe Observer. Observable: Uma representação de um objeto ou dados que estejam sendo observados por um conjunto de observers. Se o objeto é alterado todos os observers são notificados pela invocação aos respectivos métodos update() (update() é parte da interface Observer). BitSet: Conjunto dinâmico de bits (pode crescer). Operações possíveis: setar , limpar , ler, AND, OR, XOR. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 80 Util Package: outras classes utilitárias Math: funções matemáticas. (exemplo: MichaelCDaconta/Javasrc/SRC4-7.java) Date: date e time. (exemplo: MichaelCDaconta/Javasrc/SRC4-17.java) Random: classe para geração de números pseudo-aleatórios. (exemplo: MichaelCDaconta/Javasrc/SRC4-8.java) StringTokenizer: Implementa a interface Enumeration. Separa uma cadeia de caracteres (string) em seus elementos constituintes (tokens). Muito útil em parses. (exemplo: MichaelCDaconta/Javasrc/SRC4-17.java) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 81 IO em Java Segue um modelo semelhante ao de C e C++. Não existe primitivas em Java para operações de IO. As operações de IO são realizadas por classes do package java.IO. A classe java.Lang.System provê uma interface system-independent para certas funções gerais. – – – – Objeto System.in System.out System.err Tipo BufferedInputStream PrintStream PrintStream Propósito entrada padrão (keyboard) saída padrão (display) erro padrão (display) As operações de IO em Java baseiam-se no conceito de Stream. IO pode não estar disponível em applets, por questão de segurança. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 82 IO Package: File class (i) Encapsula o acesso a informação sobre arquivos ou diretórios no filesystem. Obtém informações sobre atributos dos arquivos Lista os arquivos de um diretório Remove arquivos Cria diretórios ... Todavia, não lê nem escreve em arquivos. Estas operações são realizadas por classes do tipo stream. O filesystem encontra-se fora da JVM e, portanto é suscetível a diferenças oriundas de arquitetura ou implementações (ex.: file separator = “/” em UNIX e = “\” em WINDOWS). Exemplo: ExploringJava/io/ListIt.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 83 IO Package: File class (ii) public class java.io.File extends java.lang.Object { // Fields public final static String pathSeparator; public final static char pathSeparatorChar; public final static String separator; public final static char separatorChar; // Constructors public File(File dir, String name); public File(String path); public File(String path, String name); // Methods public boolean canRead(); public boolean canWrite(); public boolean delete(); Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 84 IO Package: File class (iii) public class java.io.File extends java.lang.Object { ... //Methods ... public boolean equals(Object obj); public boolean exists(); public String getAbsolutePath(); public String getName(); public String getParent(); public String getPath(); public int hashCode(); public boolean isAbsolute(); public boolean isDirectory(); ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 85 IO Package: File class (iv) public class java.io.File extends java.lang.Object { ... //Methods ... public boolean isFile(); public long lastModified(); public long length(); public String[] list(); public String[] list(FilenameFilter filter); public boolean mkdir(); public boolean mkdirs(); public boolean renameTo(File dest); public String toString(); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 86 FileInputStream InputStream ... FilterInputStream ... DataInputStream File ... java.lang.Object RandomAccessFile OutputStream Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. DataOutputStream FilterOutputStream ... PrintStream FileOutputStream 87 ByteArrayInputStream BufferedInputStream FileInputStream DataInputStream FilterInputStream InputStream PipedInputStream LineNumberInputStream SequenceInputStream StringBufferInputStream Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. PushbackInputStream 88 ByteArrayOutputStream BufferedOutputStream FileOutputStream DataOutputStream FilterOutputStream OutputStream PrintStream PipedOutputStream Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 89 IO Package Streams: representam um fluxo de dados ou um canal de comunicação, em que se escreve de um lado e se lê do outro. InputStream/OutputStream: classes abstratas que definem a funcionalidade mínima necessária para se ler ou escrever em uma seqüência não estruturada de bytes. Todos os outros tipos de streams em Java são descendentes de InputStream/OutputStream. FileInputStream/FileOutputStream: classes com operações básicas de input e output: ler um byte ou um array de bytes; saltar alguns bytes e fechar (close) o stream. (exemplo: JavaByExampleBook/applications/IO/CopyFile.java) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 90 IO Package: InputStream (i) public abstract class java.io.InputStream extends java.lang.Object { // Constructors public InputStream(); // Methods public int available(); public void close(); public void mark(int readlimit); public boolean markSupported(); public abstract int read(); public int read(byte b[]); public int read(byte b[], int off, int public void reset(); public long skip(long n); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. len); 91 IO Package: InputStream (ii) InputStream(): Construtor padrão. Avaiable(): Modo não-bloqueado de sabermos o número de bytes disponíveis para leitura. Close(): fecha o input stream. Mark(): Assinala a posição corrente do stream. Read() read(byte b[]) read(byte b[], int off, int len) reset (): reset o stream na última posição assinalada (marked). Skip (): salta o número especificado de bytes. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 92 IO Package: InputStream (ii) public abstract int read() throws IOException – Reads the next byte of data from this input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown. – A subclass must provide an implementation of this method. – Returns: the next byte of data, or -1 if the end of the stream is reached. – Throws: IOException If an I/O error occurs. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 93 IO Package: InputStream (iii) public int read(byte b[]) throws IOException – Reads up to b.length bytes of data from this input instream into an array of bytes. – The read method of InputStream calls the the read method of three arguments with the arguments b, 0, and b.length. – Parameters: “b”: the buffer into which the data is read – Returns: the total number of bytes read into the buffer, or -1 is there is no more data because the end of the stream has been reached. – Throws: IOException If an I/O error occurs. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 94 IO Package: InputStream (iv) public int read(byte b[], int off, int len) throws IOException – Reads up to len bytes of data from this input stream into an array of bytes. This method blocks until some input is available. If the first argument is null, up to len bytes are read and discarded. – The read method of InputStream reads a single byte at a time using the read method of zero arguments to fill in the array. Subclasses are encouraged to provide a more efficient implementation of this method. Parameters: – b- the buffer into which the data is read – off- the start offset of the data – len- the maximum number of bytes read Returns: – the total number of bytes read into the buffer, or -1 is there is no more data because the end of the stream has been reached. Throws: IOException – If an I/O error occurs. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 95 IO Package: FileInputStream (i) public class java.io.FileInputStream extends java.io.InputStream { // Constructors public FileInputStream(File file); public FileInputStream(FileDescriptor fdObj); public FileInputStream(String name); // Methods public int available(); public void close(); protected void finalize(); public final FileDescriptor getFD(); public int read(); // Os métodos read são herdados de InputStream. public int read(byte b[]); public int read(byte b[], int off, int len); public long skip(long n); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 96 IO Package: ByteArrayInputStream/...Output...(i) ByteArrayInputStream/...Output...: implementa um buffer (array de bytes que pode ser usado como um inputstream/...output... Embora o array de bytes localize-se na memória, esta classe stream permite o acesso ao mesmo via read calls. Os bytes lidos são supridos pelo conteúdo do array de bytes. As aplicações também podem ler bytes de um string via o uso da classe StringBufferInputStream. Muito útil para a leitura de objetos persistentes. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 97 IO Package: ByteArrayInputStream/...Output...(ii) public class java.io.ByteArrayInputStream extends java.io.InputStream { // Fields protected byte buf[]; protected int count; protected int pos; // Constructors public ByteArrayInputStream(byte buf[]); public ByteArrayInputStream(byte buf[], int offset, int length); // Methods public synchronized int available(); public synchronized int read(); public synchronized int read(byte b[], int off, int len); public synchronized void reset(); public synchronized long skip(long n); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 98 IO Package: StringBufferInputStream (i) Implementa um StringBuffer (string modificável) que pode ser usado como um InputStream. É similar à classe ByteArrayInputStream, no sentido de que permite obter dados serialmente de um StringBuffer através de read() calls. Apenas os oito bits de mais baixa ordem de cada caracter no string são usados por esta classe. Exemplo: JustJava/examples/ch7/io/test7a.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 99 IO Package: StringBufferInputStream (ii) public class java.io.StringBufferInputStream extends java.io.InputStream { // Fields protected String buffer; protected int count; protected int pos; // Constructors public StringBufferInputStream(String s); // Methods public synchronized int available(); public synchronized int read(); public synchronized int read(byte b[], int off, int len); public synchronized void reset(); public synchronized long skip(long n); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 100 IO Package: SequenceInputStream (i) Dada uma série de InputStreams, efetivamente concatena-os, possibilitando ao programador o acesso aos mesmos como se constituissem um único (e maior) stream . Cada InputStream é lido até o final. Então a classe SequenceInputStream fecha (close) o stream e automaticamente inicia a leitura do novo stream e, assim, sucessivamente. Exemplo: JustJavaBook/examples/ch7/io/test7c.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 101 IO Package: SequenceInputStream (ii) public class java.io.SequenceInputStream extends java.io.InputStream { // Constructors public SequenceInputStream(Enumeration e); public SequenceInputStream(InputStream s1, InputStream s2); // Methods public void close(); public int read(); public int read(byte buf[], int pos, int len); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 102 IO Package: PipedInputStream/PipedOutputStream (i) Classes usadas aos pares . Possibilitam a comunicação entre dois threads via IO calls. Aquilo que um thread grava em um PipedOutputStream será lido por um outro thread que instanciou um PipedInputStream. Estas duas classes fornecem pronto um consumer-producer buffer. Exemplo: JavaAppsHopson&Ingram/Chap08/PipeApplet.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 103 IO Package: PipedInputStream (ii) public class java.io.PipedInputStream extends java.io.InputStream { // Constructors public PipedInputStream(); public PipedInputStream(PipedOutputStream src); // Methods public void close(); public void connect(PipedOutputStream src); public int read(); public int read(byte b[], int off, int len); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 104 IO Package: PipedOutputStream (ii) public class java.io.PipedOutputStream extends java.io.OutputStream { // Constructors public PipedOutputStream(); public PipedOutputStream(PipedInputStream snk); // Methods public void close(); public void connect(PipedInputStream snk); public void write(byte b[], int off, int len); public void write(int b); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 105 Envia Pedido (Write) Consumidor Obtém Resultado (Read) P i p e P i p e A B Recebe Pedido (Read) Produtor Envia Resultado (Write) Serviço Pedido Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 106 IO Package: FilterInputStream/...Output... Classe derivada de InputStream. Provê a facilidade de se ter vários níveis de InputStreams encadeados. .Cada um destes níveis modificará os dados que passam por ele de um modo determinado. Na prática FilterInputStream simplesmente faz o override do método read() do InputStream subjacente, primeiramente invocando-o e depois, retornando qualquer valor que assim desejar. Consegue-se, assim, alterar o InputStream inicial. Subclasses de FilterInputStream poderão prover o seu próprio override dos métodos e também adicionar novos métodos e data members. Classes derivadas: BufferedInputStream, DataInputStream, LineNumberInputStream, PushbackInputStream. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 107 IO Package: FilterInputStream public class java.io.FilterInputStream extends java.io.InputStream { // Fields protected InputStream in; // Constructors protected FilterInputStream(InputStream in); Methods public int available(); public void close(); public void mark(int readlimit); public boolean markSupported(); public int read(); public int read(byte b[]); public int read(byte b[], int off, int len); // public void reset(); public long skip(long n); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 108 IO Package: FilterOutputStream public class java.io.FilterOutputStream extends java.io.OutputStream { // Fields protected OutputStream out; // Constructors public FilterOutputStream(OutputStream out); // Methods public void close(); public void flush(); public void write(byte b[]); public void write(byte b[], int off, int len); public void write(int b); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 109 IO Package: FilterInputStream - Exemplo ExploringJava/io/rot13InputStream.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 110 IO Package: BufferedInputStream/...Output .... Na primeira vez em que os dados são lidos retorna-se para o usuário apenas os dados (quantidade de bytes) requisitados no read. Os dados restantes são mantidos em um buffer em memória - 2 kbytes por default, invisível para a aplicação - a fim de atender a novos reads. Só quando o buffer é esgotado é que se lê fisicamente do arquivo ByteArrayInputStream. exemplo: JavaNow/Chap10/FileIO/FileIO.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 111 IO Package: BufferedInputStream public class java.io.BufferedInputStream extends java.io.FilterInputStream { protected byte buf[]; // Fields protected int count; protected int marklimit; protected int markpos; protected int pos; public BufferedInputStream(InputStream in); // Constructors public BufferedInputStream(InputStream in, int size); public int available(); // Methods public void mark(int readlimit); public boolean markSupported(); public int read(); public int read(byte b[], int off, int len); public void reset(); public long skip(long n); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 112 IO Package: DataInputStream/...Output... Classe que provê métodos para ler, de um InputStream, os diversos tipos de dados built-in: booleans, floats, integers, etc... Outros métodos lêem uma linha do InputStream , um número determinado de bytes, etc... O método a ser chamado depende do tipo de dado esperado. Os dados nos streams de input e output sempre tomam a forma binária. Assim, p. ex., um inteiro de valor zero corresponderá a 4 bytes de 0x30, que seria o código ASCII para o string impresso “0000”. Exemplo: MichaelCDaconta/Javasrc/SRC4-17.java) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 113 IO Package: DataInputStream (i) public class java.io.DataInputStream extends java.io.FilterInputStream implements java.io.DataInput { // Constructors public DataInputStream(InputStream in); // Methods public final int read(byte b[]); public final int read(byte b[], int off, int len); public final boolean readBoolean(); public final byte readByte(); public final char readChar(); public final double readDouble(); public final float readFloat(); public final void readFully(byte b[]); public final void readFully(byte b[], int off, int len); ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 114 IO Package: DataInputStream (ii) public class java.io.DataInputStream extends java.io.FilterInputStream implements java.io.DataInput { ... public final int readInt(); public final String readLine(); public final long readLong(); public final short readShort(); public final int readUnsignedByte(); public final int readUnsignedShort(); public final String readUTF(); public final static String readUTF(DataInput in); public final int skipBytes(int n); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 115 IO Package: LineNumberInputStream (i) Classe para entrada de dados que guarda o registro do número de linhas lidas. Também fornece a possibilidade de se alterar e de se recuperar o contador de linhas (line count). O contador de linha é inicializado com zero. Uma linha é uma seqüência de bytes terminando com: i) um carriage return (‘\r’); ii) um caracter de newline (‘\n’); iii) um carriage return imediatamente seguido por um caracter de linefeed. Em todos os três casos o caracter indicativo do final da linha será retornado como um único caracter. Usualmente utilizada acoplada a outro tipo de stream. Exemplo: JustJavaBook/examples/ch7/io/test7b.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 116 IO Package: LineNumberInputStream (ii) public class java.io.LineNumberInputStream extends java.io.FilterInputStream { // Constructors public LineNumberInputStream(InputStream in); // Methods public int available(); public int getLineNumber(); public void mark(int readlimit); public int read(); public int read(byte b[], int off, int len); public void reset(); public void setLineNumber(int lineNumber); public long skip(long n); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 117 IO Package: PushbackInputStream (i) Esta classe fornece um método para colocar de volta (“push back”) no input stream, um byte que tenha sido lido. Esta é uma operação comum quando na fase de análise léxica dos compiladores. Permite que se olhe um byte à frente e, então, se decida o que fazer com o token corrente, em função do contexto. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 118 IO Package: PushbackInputStream (ii) public class java.io.PushbackInputStream extends java.io.FilterInputStream { // Fields protected int pushBack; // Constructors public PushbackInputStream(InputStream in); // Methods public int available(); public boolean markSupported(); public int read(); public int read(byte bytes[], int offset, int length); public void unread(int ch); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 119 IO Package: PrintStream (i) Esta classe implementa alguns métodos adicionais que transformam os seus argumentos em strings, colocando-os no output stream. Possui ainda, um conjunto complementar de métodos println() que adicionam um caracter de newline ao final do string. Os streams System.out e System.err são instâncias da classe PrintStream. PrintStream faz o override de vários métodos de InputStream, de modo a não lançar uma exceção de IO. O que causaria uma exceção de IO ativa um flag a que a aplicação pode ter acesso invocando o método checkError. Ex: JavaByExampleBook/Applications/Io/TokenizerText.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 120 IO Package: PrintStream (ii) public class java.io.PrintStream extends java.io.FilterOutputStream { // Constructors public PrintStream(OutputStream out); public PrintStream(OutputStream out, boolean autoflush); // Methods public boolean checkError(); public void close(); public void flush(); public void print(char c); // idem para os tipos primitivos int, long, etc... public void print(char s[]); public void print(Object obj); public void print(String s); public void println(); public void println(char c); // idem para os tipos primitivos int, long ... //métodos idênticos a print(...), só que acrescentando newline. public void write(byte b[], int off, int len); public void write(int b); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 121 IO Package: StreamTokenizer (i) Classe que possibilita uma análise léxica básica de um input stream. O input stream é particionado em seus tokens constituintes, os quais podem ser lidos um de cada vez. O processo de parsing é controlado por uma tabela e um número de flags que podem ser ativadas em vários estados. StreamTokenizer pode reconhecer identificadores, números, strings com aspas, e vários estilos de comentários. Uma aplicação típica inicialmente contrói uma instância da classe StreamTokenizer, inicializa as tabelas de sintaxe, e então executa um loop invocando repetidamente o método nextToken() em cada iteração até que seja retornado o valor TT_EOF. Ex: JavaByExampleBook/Applications/Io/TokenizerText.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 122 IO Package: StreamTokenizer (ii) public class java.io.StreamTokenizer extends java.lang.Object { // Fields public double nval; public String sval; public int ttype; // possible values for the ttype field public final static int TT_EOF; public final static int TT_EOL; public final static int TT_NUMBER; public final static int TT_WORD; // Constructors public StreamTokenizer(InputStream I); // Methods public void commentChar(int ch); public void eolIsSignificant(boolean flag); ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 123 IO Package: StreamTokenizer (iii) public class java.io.StreamTokenizer extends java.lang.Object { ... public int lineno(); public void lowerCaseMode(boolean fl); public int nextToken(); public void ordinaryChar(int ch); public void ordinaryChars(int low, int hi); public void parseNumbers(); public void pushBack(); public void quoteChar(int ch); public void resetSyntax(); public void whitespaceChars(int low, int hi); public void slashStarComments(boolean flag); public String toString(); public void whitespaceChars(int low, int hi); public void wordChars(int low, int hi); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 124 IO Package: RandomAccessFile (i) Esta classe permite que se mova o ponteiro do arquivo para uma posição arbitrária no arquivo, antes de se ler ou gravar no mesmo. Permite o acesso randômico ao arquivo. Ao se abrir o arquivo deve-se fornecer um string indicativo do modo de acesso ao arquivo: – read access only - “r – “read and update access - “rw” Exemplo: JustJavaBook/examples/ch7/io/test7e.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 125 IO Package: RandomAccessFile (ii) public class java.io.RandomAccessFile extends java.lang.Object implements java.io.DataOutput java.io.DataInput { // Constructors public RandomAccessFile(File file, String mode); public RandomAccessFile(String name, String mode); // Methods public void close(); public final FileDescriptor getFD(); public long getFilePointer(); public long length(); public int read(); public int read(byte b[]); public int read(byte b[], int off, int len); public final boolean readBoolean(); public final byte readByte(); public final char readChar(); ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 126 IO Package: RandomAccessFile (iii) public class java.io.RandomAccessFile extends java.lang.Object implements java.io.DataOutput java.io.DataInput { ... public final double readDouble(); public final float readFloat(); public final void readFully(byte b[]); public final void readFully(byte b[], int off, int len); public final int readInt(); public final String readLine(); public final long readLong(); public final short readShort(); public final int readUnsignedByte(); public final int readUnsignedShort(); public final String readUTF(); public void seek(long pos); public int skipBytes(int n); public void write(byte b[]); ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 127 IO Package: RandomAccessFile (iv) public class java.io.RandomAccessFile extends java.lang.Object implements java.io.DataOutput java.io.DataInput { ... public void write(byte b[], int off, int len); public void write(int b); public final void writeBoolean(boolean v); public final void writeByte(int v); public final void writeBytes(String s); public final void writeChar(int v); public final void writeChars(String s); public final void writeDouble(double v); public final void writeFloat(float v); public final void writeInt(int v); public final void writeLong(long v); public final void writeShort(int v); public final void writeUTF(String str); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 128 Abstract Window Toolkit Interface independente de plataforma que permite o desenvolvimento de uma GUI que pode ser executada na maior parte das plataformas existentes. Em todos os produtos cross-plataform o desenvolvedor deve escolher entre as seguintes estratégias: – mesma aparência (common look and feel) entre diferentes plataformas (Common Desktop Environment) – funcionalidade comum, com aparência específica para cada plataforma O awt adota abordagem common functionality/specific implementation. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 129 Abstract Window Toolkit Três conceitos são utilizados em JAVA AWT para implementar a “funcionalidade comum / aparência específica” da plataforma: – objetos abstratos – toolkits – peers Todos elementos de GUI suportados pelo AWT possuem uma classe. Os objetos GUI do AWT são abstrações de uma GUI independentes da plataforma (objetos abstratos). O toolkit é uma implementação, para cada plataforma específica, de todos os elementos GUI suportados pelo AWT. Cada toolkit implementa os elementos GUI específicos para cada plataforma, através da criação de um GUI peer. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 130 Abstract Window Toolkit Como ter acesso ao toolkit default e imprimir propriedades específicas da plataforma do toolkit e do hardware. Java for C/C++ Programmers. Michael C. Daconta. John Wiley & Sons, Inc. Pág. 293. SRC6-1.java Código que ilustra a criação em separado de um objeto AWT do seu peer. Java for C/C++ Programmers. Michael C. Daconta. John Wiley & Sons, Inc. Pág. 293. SRC6-2.java Deve-se ressaltar que: – peers são separados dos objetos AWT (são implementados usando a idéia de containment e, não, herança. – O peer não é criado até o momento em que existe uma representação física do screen (no exemplo, o método show do objeto myFrame, que é uma instância da classe Frame). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 131 Principais Elementos do AWT (I) Components: O elemento fundamental de toda GUI. É implementado via uma classe abstrata Component, a qual possui subclasses para implementar componentes específicos. Events: Ação do usuário que é trazuzida em uma estrutura de dados Event (armazena o tipo da ação, quando ela ocorreu, etc...) e enviada para o interpretador JAVA pelo sistema operacional. Events são enviados para serem tratados pelo componente GUI a que pertencem. Manipula-se eventos em JAVA fazendo-se o “override”do método handleEvent ou de um dos métodos específicos para tratamento de eventos na classe Component. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 132 Principais Elementos do AWT (II) Containers: São componentes que armazenam outros componentes. Layout: Trata-se de uma metodologia para dispor components em um container. Um layout determina aonde os components serão desenhados. Painting e Updating: Java provê os métodos paint(), repaint() e update() para customizar os desenhos de sua aplicação. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 133 Button Choice Component Label Canvas List Checkbox Text Component TextField Container TextArea Frame Window MenuComponent Panel Dialog Applet MenuIten MenuBar Menu FileDialog Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 134 Components (i) São os objetos que automaticamente nos vêm a mente quando pensamos em uma GUI. Canvas: Representa uma área retangular do vídeo, na qual a aplicação pode desenhar algo, ou da qual a aplicação possa capturar input events gerados pelo usuário. A aplicação deve criar uma subclasse da classe Canvas, de modo a conseguir algum nível útil de funcionalidade. Deve-se fazer um override do método paint de forma a se desenhar gráficos customizados no canvas. O AWT envia ao canvas todos os eventos de mouse, keyboard e focus que ocorrem no mesmo. (Deve-se fazer um override dos métodos gotFocus, lostFocus, keyDown, keyUp, mouseEnter, mouseExit, mouseMove, mouseDrag, mouseDown e mouseUp, de modo a se capturar os eventos do usuário. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 135 Components (ii) Containers: São components que armazenam outros components e os dispõem segundo um Layout manager. A representação em vídeo de um container é um retângulo. Portanto os components são dispostos dentro do retângulo. Existem dois tipos de components: windows e panels. Uma window é o elo entre a sua aplicação e o mundo exterior. Através dela o usuário comunica-se com a aplicação. Um panel é uma seção de uma window. Os panels possibilitam que uma window seja subdividida em subseções, cada qual com o seu próprio Layout manager. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 136 Components (iii) Containers: Um Applet é um panel que é apresentado dentro de uma janela (window) de um browse. Existem vários tipos de windows, cada uma com um propósito diferente: – Window: uma window de mais alto nível que não possui bordas (borders) e nem barra de menu (menu bar). Ideal para implementar menus pop-up. – Frame: window de mais alto nível que possui bordas e que pode ter uma barra de menu. A barra pode ter um título para o frame. – Dialog: trata-se de uma window com uma borda que é normalmente uma subwindow em uma aplicação e que é usada para se obter input do usuário. Existem os modal dialog (obrigatório o fornecimento da informação) e modeless dialog (fazer Modal = false no construtor da classe AWT dialog). – File Dialog: diálogo especial usado para abrir e salvar arquivos. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 137 Como estruturar components dentro dos containers (i) AWT GUIs devem executar em múltiplas plataformas e sistemas operacionais. Isto causa problemas para o ordenamento das coordenadas dos components, porque estes têm diferentes tamanhos em diferentes sistemas operacionais. A Interface LayoutManager descreve os métodos que uma classe deve implementar de modo a ordenar (layout) um container. Por laying out a container quer-se dizer uma classe que usa uma metodologia específica para dispor componentes dentro de um retângulo de um container (especificado por sua dimensão Dimension). Todo container deve possuir um LayoutManager. O Layout manager default é o BorderLayout. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 138 Como estruturar components dentro dos containers (ii) Métodos dos containers que são específicos para dispor os (laying out) components: public setLayout(LayoutManager mgr): associa a classe LayoutManager ao component. Existe um conjunto pré-definido de LayoutManagers que podem ser associados. Pode-se associar o LayoutManager a null e customizar-se a apresentação dos components no container usando-se o método reshape () na classe component. Isto não é recomendável porque a sua GUI provavelmente só estará correta para o seu sistema. Em outras plataformas ....!? Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 139 Como estruturar components dentro dos containers (iii) public LayoutManager getLayout(): retorna o LayoutManager corrente. public synchronized Component add(String name, Component comp): Este método adiciona um component tanto ao container quanto ao LayoutManager. Public synchronized Component add(Component comp): adiciona um component apenas ao container, e não, ao Layout manager. Os components não serão mostrados se adicionados deste modo, a menos que se chame explicitamente reshape() para cada component. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 140 Layout Managers pré-definidos para o AWT (classes pré-definidas no AWT e que implementam a interface LayoutManager) BorderLayout: Layout que representa uma conjunto de components que envolvem um component central. É implementado admitindo apenas 5 (cinco) components identificados por “North”, “South”, “East”, “West” e “Center”. Pode-se especificar gaps horizontais e verticais entre os components. FlowLayout: Layout que representa components dispostos linearmente.. É implementado dispondo-se os components ao longo de uma linha, da esquerda para a direita. GridLayout: Layout que representa uma grade simples com apenas um component por célula. É implementado especificando-se o número de linhas e colunas da grade. Todas as células são do mesmo tamanho. Os components são adicionados às células preenchendo-se, primeiro, as linhas. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 141 Layout Managers pré-definidos para o AWT (classes pré-definidas no AWT e que implementam a interface LayoutManager) GridBagLayout: Layout que representa uma grade muito flexível. É implementado via uma grade retangular de células, em que um component pode ser colocado em qualquer célula, podendo ocupar mais de uma célula. Especifica-se o local de um component alterando-se as variáveis gridx e gridy das restrições (constraints) de cada component. As variáveis gridheight e gridwidth especificam a largura e a altura de uma subgrade dentro da grade. Uma vez determinada a área em que um component será mostrado, pode-se especificar aonde, nesta área ele deverá ser ancorado, no caso da área ser maior que o component. Ver os programas SRC6-7.java e SRC6-8.java, Pág. 319 e 328 do livro: Java for C/C++ Programmers. Michael C. Daconta. John Wiley & Sons, Inc. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 142 Graphics Context (i) Todos os sistemas GUI têm o conceito de estrutura de dados gráfica, para armazenar informações específicas de contexto sobre uma área de desenho. Esta área pode ser todo o screen, parte do screen (como um único component), ou ainda uma impressora. Pode-se, assim, subdividir o monitor físico em um número arbitrário de áreas de desenho. Cada contexto gráfico (e portanto, cada área de desenho) pode possuir um conjunto diferente de características gráficas (background color, default font, line size, etc ...). – – – – MS Windows --- Device Context (DC) X Windows --- Graphics Context (GC) Macintosh --- GrafPort Java --- classe abstrata Graphic Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 143 Graphics Context (ii) Os contextos gráficos possibilitam que o desenho ocorra de modo genérico, sem especificar-se aonde o mesmo ocorrerá. Isto o torna independente do dispositivo. O graphic context é instanciado quando o método show() é invocado (similar à instanciação do toolkit e peer). É específico para cada plataforma. Ver o programa SRC6-9.java, Pág. 332 do livro: Java for C/C++ Programmers. Michael C. Daconta. John Wiley & Sons, Inc. É importante registrar-se que, ao desenharmos em contextos gráficos, se uma janela se sobrepõe à janela em que desenhamos, quando a trouxermos novamente para foreground (via click do mouse, p.ex.), os desenhos desaparecerão da janela. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 144 Graphics Context (iii) Um método especial paint é a solução para este problema e é automaticamente invocado sempre que o component (no caso, a janela) é exposto, i.e., tornado visível. Em cada component existem três métodos painting críticos: – paint(Graphics g): o método paint default de cada component nada faz. É preciso fazer-se o override deste método para desenhar no component. Este método é chamado quando o component é mostrado pela primeira vez - via invocação de show() - e, então, toda vez que a janela é novamente exposta, após ter sido coberta por outra janela. – repaint(): Sem argumentos, este método invoca o método update do component tão cedo quanto possível. Pode-se especificar um número de milisegundos para se invocar update(). – update(Graphics g): O método default limpa o component preenchendo-o com a cor de background, fixa a cor do graphic context como a cor de foreground e, então, invoca o método paint() [origem do animation flicker]. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 145 Threads Fluxo de controle Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 146 Package java.lang: Thread Class (i) Um thread é um fluxo sequencial de execução. Similar ao conceito de processo. Cada processo possui o seu próprio address space. Já os threads compartilham um mesmo address space. Um processo pode conter um ou mais threads, em um ambiente operacional que suporte multithreading. Como os threads compartilham o mesmo address space irão compartilhar as mesmas instance variables, mas não as variáveis locais. Um thread pode criar outros threads. Em Java vários threads estão presentes (Ex. Garbage Colector, paint(), etc...). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 147 Package java.lang: Thread Class (ii) Em Java há duas alternativas para se criar um novo thread: – estendendo-se a classe java.lang.Thread e fazendo-se o override do método run(). – Implementando-se a Runnable Interface. Neste caso, deve-se definir o método run(). Todo Thread em Java inicia a sua existência via a execução de um método run(). – run() deve ser public; – não pode retornar um valor; – não pode lançar (thrown) qualquer exceção. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 148 java.lang.Thread extensions class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // computa números primos maiores que minPrime ... } } // O código a seguir criaria um thread e iniciaria a sua execução ... PrimeThread p = new PrimeThread(143); p.start(); ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 149 Runnable Interface class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // computa números primos maiores que minPrime ... } } // O código a seguir instancia uma classe que implementa a Runnable Interface e cria um novo Thread passando-a como parâmetro. Inicia-se, então, o novo Thread. PrimeRun p = new PrimeRun(143); new Thread(p).start(); Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 150 Runnable Interface - código alternativo class PrimeRun implements Runnable { Thread MyThread; long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; MyThread = new Thread (this); MyThread.Start(); } public void run() { // computa números primos maiores que minPrime ... } } // O código a seguir criaria um thread e iniciaria a sua execução PrimeRun p = new PrimeRun(143); Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 151 Criando Threads - exemplos JustJavaBook/examples/ch5/thread5a.java (modos alternativos para criar threads) JavaAppsHopson&Ingram/Chap08/LineApplet1/LineApplet.java JavaAppsHopson&Ingram/Chap08/LineApplet2/LineApplet.ver1.java JavaAppsHopson&Ingram/Chap08/ LineApplet3/ LineApplet.ver2.java JavaAppsHopson&Ingram/Chap08/LineApplet4/LineApplet.ver3.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 152 Package java.lang: Thread Class (iii) Um novo Thread é criado instanciando-se a classe java.lang.Thread O objeto Thread representa um thread para o interpretador Java e serve como um handle para controlar e sincronizar a sua execução. Java é uma linguagem sem herança múltipla. Uma classe derivada de Thread não poderia, p. ex., rodar a classe Applet como um Thread. Assim, Java também implementa threads via a interface Runnable. A sua classe deve, pois, implementar Runnable e deve definir um método run(). Após, instancia-se um Thread e passa-se a classe que implementa a Runnable Interface como parâmetro. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 153 Métodos para controlar os Threads (i) start() dá início à execução do Thread. run() contém o código a ser executado no Thread. stop() acaba com o Thread. suspend() suspende (bloqueia) a execução do Thread. resume() reinicia a execução do Thread (que anteriormente invocou um suspend()). suspend() e resume() devem ser usados em situações em que o processo de setup do Thread seja muito dispendioso (abertura de sockets e comunicações mais elaboradas, p. ex.). sleep() método estático que causa um delay na execução do Thread corrente de um número específico de milisegundos. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 154 Métodos para controlar os Threads (ii) Thread.sleep() lança (throwns) uma InterruptedException se interrompido por um outro Thread. join() faz com que o thread que ativou o presente thread espere até que este último realmente esteja morto. É sempre muito perigoso não se esperar pela morte de um thread. O thread pode ativar certos objetos (ex. um applet) que não mais sejam válidos. Isto pode causar uma exceção ou travar um applet. Existem versões adicionais de join() que só esperarão por t milisegundos (time-out value). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 155 Sincronização (i) Mecanismo para sincronizar as atividades de vários threads. As classes, em java, devem ser threads-safe, i.e., vários threads devem, a princípio, utilizar concorrentemente/simultâneamente a mesma classe. Há trechos de código, as regiões críticas, que não podem ser executadas concorrentemente/simultâneamente. Deve-se sincronizar o acesso a estes trechos de código. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 156 Regiões críticas - exemplos (i) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 157 Regiões críticas - exemplos (ii) toiletes em restaurantes, aeronaves, etc... caixas de supermercado controle de estoque pilhas Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 158 Regiões críticas - exemplos (iii) class TestStack, uma pilha que não é threads-safe JavaAppsHopson&Ingram/Chap08/TestStack.java (pág. 240) JavaAppsHopson&Ingram/Chap08/StackApplet.java (pág. 238) razão: dois diferentes threads poderiam usar ao mesmo tempo TestStack, com a seguinte seqüência de código: PUSH: ++top; POP: Integer I = s[top]; POP: s[top] = null; POP: --top; PUSH: s[top] = item; No caso, pop() tentaria retornar um topo de stack que ainda não teria sido atribuído. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 159 Scheduling e Prioridades (i) Preemptive Time Scheduling: O Scheduler dá às tasks (process ou threads) pequenas fatias de tempo (time-slices) para que sejam executadas nestes intervalos. Ex.: Windows 95 e Unix. Nonpremptive Time Scheduling: uma task não dá a uma outra task a chance de ser executada, até que ela tenha terminado o seu processamento ou tenha, ela própria, cedido o seu tempo. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 160 Priority preemptive, round robin scheduling Alta Prioridade Baixa Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 161 Priority preemptive, round robin scheduling A qualquer momento, se um thread de mais alta prioridade que o thread corrente torna-se executável (runnable), ele ganha o controle da CPU em detrimento do thread corrente e inicia execução. Por default, aplica-se o schedule round robin a threads de mesma prioridade, o que quer dizer que uma vez que o trhead inicie a sua execução, a mesma continua até que o thread: Sleeps -- invoca Thread.sleep() ou wait() Espere por um lock -- para executar um método sincronizado bloqueie em I/O -- em invocações a xread() ou em accept() Explicitamente libere controle -- invoca yield() Termine -- Completa o seu método alvo (target) ou é terminado por uma invocação a stop. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 162 Priority preemptive, time-sliced scheduling Alta Prioridade Baixa Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 163 Sincronização em Java (ii) O mecanismo para sincronização das atividades dos threads é baseado no conceito de monitor (C.A.R.Hoare). Um monitor é, essencialmente um lock. É associado ao recurso a que vários threads pretendem ter acesso. Através do lock controla-se o acesso ao recurso. Java controla todo o processo de aquisição e gerenciamento dos locks. Tudo o que o usuário precisa fazer é especificar os recursos que necessitam locks. A keyword synchronized assinala os locais aonde um thread deve adquirir o lock antes de continuar. Em Java cada classe e cada instância de classe possui o seu lock. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 164 Synchronized keyword (i) class SpeechSyntethizer { synchronized void say (String words) { //implementação do método ... } } Antes de um thread X executar say() deverá adquirir um lock. Isto é dito pela keyword synchronized. Se outro thread Y já possui o lock, então o thread X deverá aguardar até que o thread Y libere o lock e, possivelmente, terá que concorrer com outros threads pelo uso do lock. Quando threads são sincronizados, apenas um thread estará executando o trecho do código. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 165 Synchronized keyword (ii) A keyword synchronized também pode ser usada para blocos de código arbitrários. Synchronized (my object) { // funcionalidade a se sincronizada .... } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 166 Synchronized keyword (iii) Synchronized void MyMethod() { .... } é equivalente a: void MyMethod() { synchronized (this) { ... } } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 167 Exemplos de Sincronização JavaAppsHopson&Ingram/Chap08/SyncTestStack.java JavaAppsHopson&Ingram/Chap08/NotifyWaitTestStack.java JavaAppsHopson&Ingram/Chap08/PipeApplet.java Exploring/threads/Clock.java Exploring/threads/UpdateApplet.java Exploring/threads/messagepasser/Consumer.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 168 A Sincronização entre Threads wait(): quando invocado libera o monitor do objeto (lock) e simplesmente espera (sem efetuar qualquer processamento adicional) até que seja notificado . Existe um método wait() alternativo com opção de timeout. notify(): é invocado por um thread X para acordar um thread que esteja em wait (esperando). O thread acordado passa a possuir o monitor (lock). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 169 Prioridades A classe Thread provê três variáveis públicas que podem ser usadas para estabelecer a prioridade do thread: MIN_PRIORITY: indica o valor mínimo de prioridade em que um thread pode ser executado. NORMAL_ PRIORITY: indica o valor default da prioridade em que um thread é executado. MAX_ PRIORITY: indica o valor máximo de prioridade em que um thread pode ser executado. Um thread executando com esta prioridade consumirá a maior parte do tempo disponível da cpu. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 170 Outros métodos da classe Thread currentThread(): retorna uma referência para o Thread corrente. getName(): obtém o nome do Thread. getPriority: retorna a prioridade do Thread. getThreadGroup: retorna o ThreadGroup do thread. isAlive: retorna se o Thread está ativo, i. e., foi ativado via start, mas ainda não morreu (stop). run(): método que define a atividade do Thread. setDaemon(): estabelece o Thread como um daemon. setPriority(): fixa uma prioridade para o Thread. yield(): concede o time-slice do Thread corrente para um outro Thread. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 171 public class java.lang.Thread extends java.lang.Object implements java.lang.Runnable { // Fields public final static int MAX_PRIORITY; public final static int MIN_PRIORITY; public final static int NORM_PRIORITY; // public public public public public public Constructors Thread(); Thread(Runnable target); Thread(Runnable target, String name); Thread(String name); Thread(ThreadGroup group, Runnable target); Thread(ThreadGroup group, Runnable target, String name); public Thread(ThreadGroup group, String name); Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 172 // Methods public public public public public public public public public public public public public public public public static int activeCount(); void checkAccess(); int countStackFrames(); static Thread currentThread(); void destroy(); static void dumpStack(); static int enumerate(Thread tarray[]); final String getName(); final int getPriority(); final ThreadGroup getThreadGroup(); void interrupt(); static boolean interrupted(); final boolean isAlive(); final boolean isDaemon(); boolean isInterrupted(); final void join(); Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 173 // Methods ... public final void join(long millis); public final void join(long millis, int nanos) public final void resume(); public void run(); public final void setDaemon(boolean on); public final void setName(String name); public final void setPriority(int newPriority); public static void sleep(long millis); public static void sleep(long millis, int nanos) public void start(); public final void stop(); public final void stop(Throwable obj); public final void suspend(); public String toString(); public static void yield(); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 174 Applets public class HelloMan extends Applet { public void paint(Graphics g) { g.drawString("Hello, world", 0, 20); } } <HTML> <HEAD> <TITLE>Hello World</TITLE> </HEAD> <BODY> <APPLET CODE="HelloMan.class" WIDTH=250 HEIGHT=100> </APPLET> </BODY> </HTML> Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 175 import java.applet.Applet; import java.awt.*; A classe Applet (i) Applets são programas que podem ser embutidos em páginas WEB (documentos html). Podem ser executados por browsers WEB ou pelos Appletviewers. Todos os applets estendem a classe Applet, a qual inclui métodos que permitem operações próprias de ambientes em redes. Estes métodos permitem carregar recursos de um servidor WEB e acompanhar o progresso do download. O Applet é também um panel, que é um tipo de container. Pode, portanto ter vários components e capturar eventos (gerados via teclado, mouse, etc...). Os applets podem implementat Threads através da Runnable Interface. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 176 html docs x applets Os applets são referenciados nas páginas WEB (documentos html) através da tag html APPLET. <html> <head><title>Exemplo de Applet embutido em uma página html </title></head> <body> ... <applet code="AudioItem" width=15 height=15> <param name=snd value="Hello.au|Welcome.au"> Java applet that plays a welcoming sound. </applet> ... </body> </html> Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 177 <!ELEMENT APPLET - - (PARAM | %text)*> <!ATTLIST APPLET codebase %URL #IMPLIED -- code base -code CDATA #REQUIRED -- class file -alt CDATA #IMPLIED -- for display in place of applet -name CDATA #IMPLIED -- applet name -width %Pixels #REQUIRED -- suggested width in pixels -height %Pixels #REQUIRED -- suggested height in pixels -align %IAlign #IMPLIED -- vertical or horizontal alignment -hspace %Pixels #IMPLIED -- suggested horizontal gutter -vspace %Pixels #IMPLIED -- suggested vertical gutter -> <!ELEMENT PARAM - O EMPTY> <!ATTLIST PARAM name NMTOKEN #REQUIRED -- The name of the parameter -value CDATA #IMPLIED -- The value of the parameter -> 178 Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. Métodos básicos da classe Applet Todo applet possui os seguintes métodos: init(): invocado na primeira vez em que o applet é carregado (ou sempre que o mesmo é recarregado) pelo browser. start(): invocado sempre que o applet mostrado. stop(): invocado sempre que o applet torna-se oculto. destroy(): invocado quando o usuário abandona o applet. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 179 Alguns exemplos de Applets JavaNow/Chap13/CrossHair/CrossHair.java JavaNow/Chap13/CrossHair2/CrossHair.java JavaNow/Chap13/ConnectTheDots/ConnectTheDots.java JavaNow/Chap13/ConnectTheDots2/ConnectTheDots.java JavaNow/Chap13/ScreenType/ScreenType.java JavaNow/Chap13/ScreenType2/ScreenType.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 180 Métodos da classe Applet para operações em networks (i) CodeBase: diretório, no servidor, de onde provém o applet. DocumentBase (Code): diretório, no servidor, de onde provém o documento html em que o applet se acha embutido. public URL getDocumentBase(): retorna a URL da página html que contém o applet, no servidor. public URL getCodeBase() retorna a URL do diretório do applet, no servidor. ElliotteRustyHarold/java.netprog/javanetexamples/06/AppletBases.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 181 Métodos da classe Applet para operações em networks: downloading imagens (i) public Image getImage (URL u) recupera a imagem localizada na URL especificada e coloca-a em um objeto do tipo imagem. Este método depende do AppletContext (do browser WEB ou do applet viewer) para recuperar e interpretar a imagem. Assim, só pode recuperar imagens nos formatos aceitáveis pelo AppletContext. ElliotteRustyHarold/java.netprog/javanetexamples/06/ImageView.java public Image getImage(URL path, String, filename) método similar ao anterior Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 182 Métodos da classe Applet para operações em networks: downloading imagens (ii) O método getImage() ,p. ex., retorna imediatamente, ainda mesmo antes de saber se a imagem realmente existe. A imagem não é carregada até que alguma outra parte do programa realmente tente desenhá-la, ou se explicitamente força o download. Neste ponto, o interpretador JAVA inicia um novo thread, em separado do thread principal do programa, para fazer o download e processar o arquivo de imagens. As imagens são processadas assincronamente. O programa pode fazer outra coisa enquanto se processa o download. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 183 Métodos da classe Applet para operações em networks: downloading imagens (iii) A operação assíncrona das imagens trás alguns problemas: – como sabermos que o download da imagem já foi efetuado? – e se desejarmos trabalhar com os dados da imagem à medida que eles cheguem? – e se desejarmos saber algo sobre as propriedades da imagem antes de podermos realmente trabalharmos com a mesma? – e se acontecer algum erro durante o download da imagem? Objetos ImageObservers tratam estes problemas. Eles implementam a interface ImageObserver. Todas as operações que desenham ou examinam objetos Image retornam imediatamente, todavia elas recebem um objeto ImageObserver como parâmetro. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 184 A Interface ImageObserver (i) A interface java.awt.image.ImageObserver permite que: – um objeto monitore o processo de download (se a imagem está completa, se houve erro, recebe informações sobre os atributos da imagem - width e height, etc...). – o usuário seja informado e use a imagem o mais rápido possível, assim que ela estiver disponível. Java.awt.Component implementa a interface ImageObserver. (cada Component é o seu próprio ImageObserver default) Um applet, p. ex., serve como um ImageObserver e invoca repaint() implicitamente, a fim de redesenhar a imagem, quando necessário. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 185 A Interface ImageObserver (ii) Exemplo: g.drawImage(thisImage, 0, 0, this) // em um applet – this é um ImageObserver no exemplo. – Se a imagem está completa ela é desenhada e pronto. – Se a imagem não está completa o método ImageUpdate() do Component será invocado periodicamente, dando uma chance de se checar o estado da imagem e responder de acordo. – Graphics.drawImage() retorna um boolean. O boolean diz se a imagem foi, ou não, desenhada com sucesso (true= OK). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 186 A Interface ImageObserver (iii) public interface java.awt.image.ImageObserver { // flags for the infoflags argument to imageUpdate public final static int ABORT; public final static int ALLBITS; public final static int ERROR; public final static int FRAMEBITS; public final static int HEIGHT; public final static int PROPERTIES; public final static int SOMEBITS; public final static int WIDTH; // Methods public abstract boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 187 A Interface ImageObserver (iv) Outros métodos que têm um objeto ImageObserver como argumento: – Image.getWidth(ImageObserver) – Image.getHeight(ImageObserver) – Image.getProperty(String, ImageObserver) – Component.checkImage(Image, ImageObserver) – Component.checkImage(Image, int, int, ImageObserver) – Component.prepareImage(Image, ImageObserver) – Component.prepareImage(Image, int, int, ImageObserver) – ComponentPeer.checkImage(Image, int, int, ImageObserver) – ComponentPeer.prepareImage(Image, int, int, ImageObserver) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 188 A Interface ImageObserver (v) A passagem de um objeto ImageObserver como parâmetro a qualquer um dos métodos anteriores sinaliza que o ImageObserver está interessado na imagem e deve ser notificado quando o estado da imagem se alterar. Se a imagem ainda não está disponível, o método ImageUpdate() do Component será invocado periodicamente, quando necessário, pelo objeto ImageObserver. Ele não é invocado explicitamente pelo usuário. ImageUpdate(): retorna: – false se a imagem está completa e não mais precisa ser atualizada. – true se a imagem ainda precisa ser atualizada, i.e., ainda não está completa. The ImageUpdate() method answers the question: Does this image need to be updated? Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 189 A Interface ImageObserver (vi) A sua implementação de ImageUpdate() precisa fazer 3 coisas: – Verificar o que se alterou na imagem, via o uso das constantes mneumônicas infoflags; – Realizar qualquer ação necessária para atualizar o estado do programa em execução; – Retorna true se precisa de updates adicionais e false se toda a informação necessária sobre a imagem já está disponível. Infoflags: combinação de constantes mneumônicas que indicam que informação sobre a imagem está disponível ElliotteRustyHarold/java.netprog/javanetexamples/06/ShowImage.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 190 Constantes infoflags • • • • • • • • ImageObserver.WIDTH = 1 ImageObserver.HEIGTH = 2 ImageObserver.PROPERTIES = 4 ImageObserver.SOMEBITS = 8 ImageObserver.FRAMEBITS = 16 ImageObserver.ALLBITS = 32 ImageObserver.ERROR = 64 ImageObserver.ABORT = 128 Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 191 Métodos da classe Applet para operações em networks: downloading sons (i) Métodos play(): executam o download do arquivo de som e imediatamente o tocam. Métodos getAudioClip(): salvam o arquivo de som para posteriormente tocá-lo. O AppletContext do browser ou do Applet viewer executa o trabalho de download e de tocar o arquivo de som. public void play(URL u): Procura por um arquivo de som na URL u. Se o arquivo é encontrado executa o download e toca-o. Em caso contrário nada acontece. public void play(URL u, String filename) ElliotteRustyHarold/java.netprog/javanetexamples/06/PlaySound.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 192 Métodos da classe Applet para operações em networks: downloading sons (ii) public AudioClip getAudioClip(URL u) A interface AudioClip representa um som. getAudioClip() faz o download de um arquivo de som de um site WEB. Uma vez de posse do objeto AudioClip, pode-se tocá-lo invocandose os métodos do clip: play() e loop(). AudioClip.play(): toca o arquivo uma vez. AudioClip.loop(): toca o arquivo repetidamente. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 193 Métodos da classe Applet para operações em networks: downloading sons (iii) AudioClip.play() e AudioClip.loop() permitem guardar o clip de áudio para uso futuro. Nos métodos play anteriores os dados do arquivo de som são descartados após serem tocados. public AudioClip getAudioClip(URL u, String filename) ElliotteRustyHarold/java.netprog/javanetexamples/06/RelativeGong.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 194 Java.awt.MediaTracker (i) Classe utilitária que monitora o download de uma imagem ou grupo de imagens (audio clips) e permite-nos verificar o seu estado periodicamente, ou esperar até que a operação esteja completa. Como usar um MediaTracker: – i) criar uma instância da classe MediaTracker. – ii) invocar o método addImage() para cada imagem a ser monitorada. Pode-se associar um identificador único para cada imagem. O identificador controla tanto a ordem de prioridade em que as imagens são trazidas, como possibilita a identificação única de subsets de imagens que podem ser carregadas independentemente. Imagens com um id baixo são carregadas preferencialmente àquelas com id alto. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 195 Java.awt.MediaTracker (ii) Antes de se usar a imagem deve-se usar um método como checkID() para verificar se a imagem já está pronta. Outros métodos permitem que se: – force o início do download; – descubra quais as imagens em um grupo não conseguiram ser carregadas; – espere pelo término do processo de download das imagens, etc... ElliotteRustyHarold/java.netprog/javanetexamples/06/trackImage.java myexamples/ImageBlaster.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 196 Java.awt.MediaTracker (ii) public class java.awt.MediaTracker extends java.lang.Object { // Fields public final static int ABORTED; public final static int COMPLETE; public final static int ERRORED; public final static int LOADING; // Constructors public MediaTracker(Component comp); // Methods public void addImage(Image image, int id); public void addImage(Image image, int id, int w, int h); public boolean checkAll(); public boolean checkAll(boolean load); public boolean checkID(int id); public boolean checkID(int id, boolean load); ... Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 197 Java.awt.MediaTracker (iii) ... // Methods ... public Object[] getErrorsAny(); public Object[] getErrorsID(int id); public boolean isErrorAny(); public boolean isErrorID(int id); public int statusAll(boolean load); public int statusID(int id, boolean load); public void waitForAll(); public boolean waitForAll(long ms); public void waitForID(int id); public boolean waitForID(int id, long ms); } Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 198 Métodos de Java.awt.MediaTracker (i) public MediaTracker(Component comp) construtor para criar um objeto MediaTracker que monitora as imagens para um dado Component. public void addImage(Image img, int id) Adiciona o objeto img (do tipo Image) à lista das imagens monitoradas pelo objeto MediaTracker e associa a img um id. public void addImage(Image img, int id, int w, int h) ... A imagem será eventualmente redimensionada tendo em vista as dimensões w e h. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 199 Métodos de Java.awt.MediaTracker (ii) public boolean checkID(int id) Verifica se todas as imagens com o ID dado que estão sendo monitoradas pelo MediaTracker terminaram o processo de download. Em caso afirmativo retorna true, senão false. Vários objetos Image podem partilhar o mesmo IDI. public synchronized boolean checkID(int id, boolean load) ... Se o argumento load (boolean) é true, todas as imagens com aquele ID que ainda não iniciaram o processo de download passam a fazê-lo. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 200 Métodos de Java.awt.MediaTracker (iii) public synchronized boolean checkAll(boolean load) Verifica se todas os objetos Image monitorados pelo MediaTracker terminaram o processo de download. Em caso positivo retorna true, senão, false. Se o argumento load (boolean) é true, inicia a carga de qualquer objeto que ainda não tenha sido carregado Os métodos wait() iniciam o download dos objetos Image monitoradas pelo MediaTracker e, então ficam bloqueados (wait) até que as imagens terminem o download. Caso você não deseje que o seu programa fique em wait esperando as imagens, invoque estes métodos em um novo thread. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 201 Métodos de Java.awt.MediaTracker (iv) public void waitForID(int id) throws InterruptedException Força as imagens com o id dado, que são monitoradas por este MediaTracker, a iniciar o loading e, então, espera (wait) até que cada uma tenha terminado o loading, abortado ou recebido um erro. Uma exceção é lançada se um outro thread interromper este thread. public synchronized boolean waitForID(int id, long ms) throws InterruptedException ... Ou até que ms milisegundos tenham sido transcorridos. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 202 Métodos de Java.awt.MediaTracker (v) public synchronized boolean waitForAll() throws InterruptedException Inicia o loading de todas as imagens que são monitoradas por este MediaTracker, e, então, espera (wait) até que cada uma tenha terminado o loading, abortado ou recebido um erro. Uma exceção é lançada se um outro thread interromper este thread. Este método deve ser usado por applets de animação a fim de carregar todos os frames antes de iniciar a apresentação dos slides. public synchronized boolean waitForAll(long ms) throws InterruptedException Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 203 Métodos de Java.awt.MediaTracker (vi) Se há um erro quando um objeto Image é carregado ou redimensionado, o objeto Image é considerado completo, encerrando-se o processo de loading. public synchronized boolean isErrorAny() Verifica se um erro ocorreu durante a carga de qualquer imagem monitorada por este MediaTracker. public synchronized Object[] getErrorsAny() Retorna um array contendo todos os objetos monitorados por este MediaTracker e que apresentaram erro durante a carga. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 204 Métodos de Java.awt.MediaTracker (vii) public synchronized boolean isErrorID(int id) Retorna true se qualquer objeto com o ID especificado apresentou um erro enquanto carregava; senão retorna false. public synchronized Object[] getErrorsID(int id) Retorna um array contendo todos os objetos com o ID especificado e que apresentaram erro durante a carga. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 205 Métodos de Java.awt.MediaTracker (viii) É possível checar o estado de grupos de objetos Image , porém não de objetos isolados. Media Status Constants – MediaTracker.LOADING = 1 - pelo menos um objeto Image do grupo ainda está em processo de download. – MediaTracker.ABORTED = 2 - o processo de loading abortou para pelo menos um objeto Image do grupo. – MediaTracker.ERRORED = 4 - Um erro ocorreu durante o processo de loading para pelo menos um objeto Image do grupo. – MediaTracker.COMPLETE = 8 - pelo menos um objeto Image do grupo foi carregado com sucesso. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 206 Métodos de Java.awt.MediaTracker (ix) public int statusAll(boolean load) Retorna o status de todos os objetos monitorados por este MediaTracker. Se o argumento load é true qualquer objeto que ainda não iniciou o loading vai iniciá-lo. Em caso contrário, não. public int statusID(int id, boolean load) Retorna o status de todos os objetos que compartilham o id especificado e que são monitorados por este MediaTracker. Se o argumento load é true qualquer objeto com o id especificado e que ainda não iniciou o loading vai iniciá-lo. Em caso contrário, não. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 207 Transmissão de Informação na Internet Datagrama = Header + Payload Header = (Address + Port)source + (Address + Port)destination + (informações para permitir a transmissão confiável) Payload = os dados Protocolos: – Connection Oriented (TCP - Transmission Control Protocol) – Connectionless (UDP - User Datagram Protocol) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 208 O Paradigma Cliente-Servidor (i) Solução para o problema do “rendevous” prog A prog B host X host Y Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. O Paradigma Cliente-Servidor (ii) Solução no Modelo Cliente / Servidor Em qualquer par de aplicações que se comuniquem, um lado deve iniciar a execução e esperar indefinidamente que o outro lado o contacte. Servidor: O programa que aguarda os pedidos dos clientes. Cliente: O programa que toma a iniciativa de iniciar a comunicação. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. O Paradigma Cliente-Servidor na Internet clientes - “sw” servidores - “sw” ports ftp server ftp client telnet 23 Netscape smtp 25 Host A - “HW” httpd http 80 smtp s. Host B - “HW” /etc/services - quais são as portas associadas a que serviços Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. World Wide Web host 1 - br host 2 - ca rerererre ytghgfhg gfhgfhgfh nnbvnbnb ffdf 999 ooiopiopop pooopioiop poiipoiopi uiouuioui iuiouuuiui nmm,mnm rerererre ytghgfhg gfhgfhgfh nnbvnbnb host 3 - br ooiopiopop pooopioiop poiipoiopi uiouuioui iuiouuuiui nmm,mnm rerererre ytghgfhg gfhgfhgfh nnbvnbnb jjlkdjjdjjj dsdadadd dsdasd ooiopiopop pooopioiop poiipoiopi uiouuioui iuiouuuiui nmm,mnm ooiopiopop pooopioiop poiipoiopi uiouuioui iuiouuuiui nmm,mnm rerererre ytghgfhg gfhgfhgfh nnbvnbnb hfhgfh jjghjhgjhg kjlkjlllllll rerererre ytghgfhg gfhgfhgfh nnbvnbnb lljkljkl khjkhjkkk rerererre ytghgfhg gfhgfhgfh nnbvnbnb ffdf 999 ooiopiopop pooopioiop poiipoiopi uiouuioui iuiouuuiui nmm,mnm host 4 - fr World Wide Web host 5 - us java.net.InetAddress (i) uma unstância de java.net.InetAddress representa um endereço na Internet data members: – String hostName; – int address (32 bit IP address) Não há construtores public Há três métodos estáticos que retornam objetos InetAddress Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 214 java.net.InetAddress (ii) public static InetAddress InetAddress.getByName(String hostame) usa o DNS para retornar o endereço IP do host. InetAddress address = InnetAddress.getByName(“www.lncc.br”) public static InetAddress[] InetAddress.getByName(String hostame) (para máquinas com vários Ips - endereços Internet) public static InetAddress InetAddress.getLocalHost() (retorna o endereço IP da máquina que está executando o programa) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 215 java.net.InetAddress (iii) Métodos para se obter o valor dos DataMembers: public String getHostName() retorna um String que contém o hostname do objeto public byte[] get.Address() retorna um endereço IP como um array de bytes em network byte order; o byte mais significativo do endereço IP é o 10 byte do array; os bytes retornam sem sinal; bytes com valor >= 127 são tratados como números negativos int unsignedByte = myByte <0 ? myByte + 256 : myByte Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 216 java.net.InetAddress (iv) Métodos herdados da classe Object e que sofrem override: public boolean equals(Object myObject) public int HashCode() retorna um int, quando os objetos InetAddress são usados como chaves em hash tables. public String toString() ex.: método invocado implicitamente objetos InetAddress são passados como argumentos para System.out.println(). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 217 java.net.URL (i) Ë a forma mais simples de um programa JAVA localizar e recuperar dados na Internet. Não precisa se preocupar com: – protocolo – o formato dos dados (que se deseja recuperar) – Atualmente JAVA só pode manipular poucos protocolos e content types (formatos de dados) O usuário pode adicionar novos protocol handles e content types. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 218 java.net.URL (ii) É uma abstração para uniform resource locator (URL) URL inclui: protocol, hostname, port, path, filename e document section. Os campos de java.net.URL só são visíveis às classes do package java.net. Todavia, pode-se recuperá-los via acessors (get methods) e inicializá-los via construtores. JDK 1.02 suporta: http, ftp, news, mailto, gopher, files URLs. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 219 java.net.URL (iii) Construtores: public URL URL (String url) throws MalformedURLException public URL URL(String protocol, String host, String file) throws MalformedURLException public URL URL(String protocol, String host, int port, String file) throws MalformedURLException para usar com portas não default public URL URL(URL u, String s) throws MalformedURLException Constrói uma URL absoluta, a partir de uma URL relativa Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 220 java.net.URL (iv) Outras fontes de objetos URL: – getDocumentBase() - da classe java.applet.Applet - pg. html – getCodeBase() - da classe java.applet.Applet - dir. do applet Particionamento de uma URL - como recuperar os data members (fields) da classe URL. – public String getProtocol() – public String getHost() – public int getPort() – public String getFile() – public String getRef() // retorna a named aanchor da URL Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 221 java.net.URL (v) Como Recuperar dados da URL: public final InputStream openStream() throws java.io.IOException – estabelece uma conexão com o recurso referenciado pela URL especificada – executa o handshake entre o cliente e o servidor – retorna um InputStream de onde os dados podem ser lidos – os dados do InputStream são raw data correspondente ao conteúdo do arquivo referenciado pela URL Exemplo: ElliotteRustyHarold/05/viewsource.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 222 java.net.URL (vi) Se desejarmos ver os headers do protocolo deveremos usar o método openConnection(). Para recuperar os dados de um .GIF ou .JPEG pode-se ler o InputStream byte a byte com readByte(). Caso se deseje processar um arquivo de um determinado tipo (ex. html), a melhor abordagem é escrever um content handler para arquivos html e, então, invocar getContent(). Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 223 java.net.URL (vii) public URLCOnnection openConnection() throws java.io.IOException – abre um socket para a URL especificada e retorna um objeto URLConnection – o objeto URLConnection representa uma conexão aberta para um recurso da Internet. – usado para comunicação direta com o servidor – além dos dados do arquivo recebe todos os headers do protocolo Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 224 java.net.URL (viii) public final Object getContent() throws java.io.IOException – outra forma de fazer o download dos dados referenciados pela URL – getContent() tenta construir um objeto: texto em ASCII ou html --- algum tipo de InputStream .GIF ou JPEG --- ImageProducer – getContent() opera via o campo Content-type do MIME header dos dados que ele recupera do servidor. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 225 java.net.URL (ix) – se o servidor não usa MIME headers ou envia um Content-type não familiar lança uma ClassNotFoundException.. – lança uma IOException se o objeto não pode ser recuperado. – a maior parte dos tipos de dados ainda não é suportada por Java – usar o operador instanceof para ver o tipo do objeto retornado. Exemplo: ElliotteRustyHarold/05/getObject.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 226 java.net.URL (x) Métodos utilitários da classe URL public boolean samefile (URL other) – verifica se dois objetos URL apontam para o mesmo recurso. – Compara apenas a URL e não o conteúdo dos arquivos (www.lncc.br é diferente de www.lncc.br:80) public String toExternalForm() – retorna um string que representa a URL – método redundante e equivalente a toString Métodos da classe Object que sofrem override pela classe URL: – public String toString() – public boolean equal(Object o) – public int hashCode() Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 227 java.net.URL (xi) public static synchronized void setURLStreamHandlerFactory (URLStreamHandlerFactory fac) É responsável por fazer o parsing da URL - recuperar o tipo de protocolo - e, então construir o objeto URLConnection apropriado para manipular a conexão com o servidor. A classe URL encoder codifica todos os caracteres da URL que não sejam letras, dígitos, e underscore. – como codificar: percentsign (%) + dois dígitos hexadecimais com o valor ASCII do caracter (space = %20) – public static String encode(String s) retorna um novo string com a URL devidamente codificada Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 228 Sockets Socket – Inovação do Berkeley UNIX – Permite ao programador tratar uma conexão em rede como qualquer outro stream de dados, em que se pode ler ou gravar. – Semelhante a arquivos, inclusive usando ss mesmas funções para ler, gravar, etc ... – A comunicação é bidirecional (full duplex) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 229 Operações Básicas dos Sockets 1. Estabelecer uma conexão com um host remoto (para enviar e receber dados) 2. Enviar dados 3. Receber Dados 4. Fechar a conexão 5. Associar-se (bind) a uma porta 6. Escutar (listen) os dados que chegam 7. Aceitar conexões de máquinas remotas na porta especificada 1, 2, 3 e 4 --- Clientes e Servidores --- classe java.net.Socket 5, 6 e 7 --- Servidores --- classe java.net.ServerSocket Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 230 Cliente Servidor início Aceita conexões Cria o socket protocolo Cria o Server-socket Troca de dados Close socket protocolo Close socket fim Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 231 A Comunicação Cliente-Servidor: Abrindo uma Conexão Quando um servidor está executando, ele está ouvindo uma porta e esperando pela ocorrência de uma conexão. Tecnicamente falando, o cliente abre um “socket” e associa este “socket” com a porta. Como em UNIX tudo é arquivo, um “socket” é um tipo especial de arquivo que possibilita I/O para a rede. Quando se abre um “socket”, do ponto de vista do cliente está se criando um arquivo virtual. Quando se escreve neste arquivo, na realidade está se enviando dados para a rede Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. java.net.Socket (i) Construtores public Socket (String host, int port) throws UnknownHostException, IOException Cria um socket TCP na porta dada do host remoto e intenta conectar-se ao mesmo. Exemplo: ElliotteRustyHarold/07/lookForPorts.java public Socket (InetAddress host, int port) throws IOException Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 233 java.net.Socket (ii) public Socket (Strinh host, int port, InetAddress interface, int localPort) throws IOException (só em Java 1.1) Cria um socket TCP na porta dada do host especificado (dois 1os argumentos) e tenta conectar-se. A conexão é feita a partir da interface de rede e da porta local especificados nos dois últimos argumentos. Se localPort = 0 escolhe uma das poras livres disponíveis. public Socket (InetAddress host, int port, InetAddress interface, int localPort) throws IOException (só em Java 1.1) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 234 java.net.Socket (iii) protected Socket() (só em Java 1.1) – usado para construir uma subclasse de Socket e implementar um tipo especial de Socket. – inicializa a superclasse sem conectar o socket. – instala o SocketImpl default (factory ou java.net.PlainSocketImpl). – a maior parte da implementação do novo tipo de Socket (nova classe) será escrita num objeto SocketImpl. protected Socket(SocketImpl impl) (só em Java 1.1) – instala o objeto SocketImpl impl quando cria o novo objeto Socket. – O objeto Socket é criado, mas não conectado. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 235 java.net.Socket (iv) Como obter informações sobre um socket: public InetAddress getInetAddress() retorna o IP do host. public int getPort() retorna a porta, no host remoto, em que o socket está conectado. public int getLocalPort() a porta local é escolhida pelo sistema em run time dentre as portas livres disponíveis . public InetAddress getLocalAddress() diz em que network interface o socket está conectado. Exemplo: ElliotteRustyHarold/07/getSocketInfo.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 236 java.net.Socket (v) Lendo e Gravando em Sockets: public InputStream getInputStream() throws IOException – retorna um raw input stream que pode ser usado pelo programa para ler dados do socket. – normalmente encadeia-se o InputStream em um DataInputStream para maior funcionalidade. – Exemplo: ElliotteRustyHarold/07/daytimeClient.java public OutputStream getOutputStream() throws IOException – retorna um raw output stream que pode ser usado pelo programa para gravar dados na outra ponta do socket. – Exemplo: ElliotteRustyHarold/07/echoClient.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 237 java.net.Socket (vi) public synchronized void close() throws IOException – método para fechar a conexão. – Boa prática de programação, especialmente levando-se em conta servidores, que rodam por um período indefinido de tempo. Métodos da classe Object: – Apenas o método toString sofre override. Exemplo: ElliotteRustyHarold/07/finger.java Exemplo: ElliotteRustyHarold/07/whois.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 238 Ciclo de Vida de um Servidor (i) 1. Cria-se um novo ServerSocket em uma porta determinada (construtor ServerSocket()). 2. O ServerSocket escuta (listens)a porta usando o método accept(), esperando por novas conexões. accept() bloqueia o servidor até que um cliente tente uma conexão. Neste ponto accept() retorna um objeto socket que conecta o cliente ao servidor. 3. Efetua-se a ocnversação entre o cliente e o servidor, de acordo com um determinado protocolo. (Os métodos getInputStream() e getOutputStream() são usados, respectivamente, para ler e gravar no socket.) Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 239 Ciclo de Vida de um Servidor (ii) 4. O servidor ou o cliente (ou ambos) fecham a conexão. 5. O servidor retorna ao passo 2 e espera por novas conexões. Freqüentemente instancia-se um novo thread para cada nova conexão (passos 3, 4 e 5 do ciclo de vida ) Exemplo:ExploringJava/net/httpd/TinyHttpd.java Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 240 java.net.ServerSocket (i) Construtores: public ServerSocket(int port) throws IOException, BindException – cria um server socket na porta especificada. – se port = 0, escolhe uma porta dentre as disponíveis (anonymous port). – Exemplo: ElliotteRustyHarold/08/lookForLocalPorts.java public ServerSocket(int port, int queuelength) throws IOException, BindException – cria um ServerSocket na porta dada, com um tamanho de fila pré-determinado. – recusa novas conexões se #conexões > queuelength. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 241 java.net.ServerSocket (ii) public ServerSocket(int port, int queuelength, InetAddress bindAddress) throws IOException (java 1.1) – cria um ServerSocket na porta dada, com um tamanho de fila pré-determinado. – recusa novas conexões se #conexões > queuelength. – Este construtor é útil para servidores com múltiplos endereços IP. O ServerSocket só se associa (binds) com o endereço IP local especificado. Protected ServerSocket (java 1.1) – Usado em subclasses de ServerSocket quando se quer prover um SocketImpl próprio, talvez para implementar protocolos de segurança ou transitar via um proxy server. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 242 java.net.ServerSocket (iii) public Socket accept() throws IOException – método invocado quando todo o set up do servidor já terminou e ele está pronto para aceitar conexões. – bloqueia, i. e., suspende o fluxo de execução, e espera até que um cliente se conecte. – quando o cliente se conecta, retorna um objeto Socket. – usa-se então, os métodos getInputStream e getOutputStream no Socket retornado para efetivar a comunicação com o cliente. Exemplo: ElliotteRustyHarold/08/daytimeServer.java public void close() throws IOException – ServerSocket close - libera a porta no host local, possibilitando a um outro server associar-se (binds) à porta. – Server close - quebra a conexão entre os hosts local e remoto. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 243 java.net.ServerSocket (iv) public InetAddress getInetAddress() retorna o endereço IP do servidor (local host). public int getLocalPort() ServerSocket faz o override do método toString da classe Object. Exemplo: ElliotteRustyHarold/08/clientTester.java particularmente interessante para testar clientes, de forma similar à usada pelo telnet para testar servidores. Exemplo: ElliotteRustyHarold/08/Redirector.java Um redirecionador. Copyright ©1997 by Oscar Luiz Monteiro de Farias, D.Sc. 244