9cm x 24cm
16,7cm x 24cm
31,5mm
16,7cm x 24cm
9cm x 24cm
JAVA 8
Y
CM
MY
CY
CMY
K
Uma obra que ajuda estudantes e profissionais a compreenderem os sistemas de gestão de bases de dados relacionais. Com apresentação dos conceitos fundamentais, inclui variados exemplos e exercícios. Aprenda as regras e boas práticas na análise, conceção e desenvolvimento de aplicações orientadas pelos objetos, através de vários projetos de software e exercícios analisados e implementados em JAVA.
Este livro dá-lhe uma panorâmica geral e atual das redes de sensores sem fios: conceitos, tecnologias, protocolos, fundamentos, sistemas operativos. Com exercícios resolvidos para TinyOS e ContikiOS.
. . .
Os conceitos e as construções intrínsecas ao paradigma da POO em JAVA; Todas as construções funcionais introduzidas em Java 8; Outras construções modernas introduzidas na linguagem.
Neste livro abordam-se todas as questões sintáticas, técnicas, pragmáticas e metodológicas do desenvolvimento de aplicações de POO em JAVA moderno, usando a versão Java 8 e seguindo as melhores práticas da Engenharia de Software. São destinatários deste livro alunos dos ensinos superior, secundário e profissional, bem como profissionais e autodidatas. Todos os que pretendem iniciar-se no paradigma da POO usando JAVA deverão realizar uma leitura sequencial da obra, que é de grau de dificuldade crescente. Aqueles que já possuem conhecimentos de POO e de JAVA poderão atualizá-los realizando leituras temáticas específicas em função das suas necessidades de aprendizagem ou curiosidade.
ISBN 978-972-722-838-6
9 789727 228386
Código fonte de todos os exemplos apresentados e testados disponível em www.fca.pt até o livro se esgotar ou ser publicada nova edição atualizada ou com alterações.
POO + Construções Funcionais
M
Dada a sua importância e a revolução que provocou no modelo de programação com as coleções, as novas construções funcionais introduzidas em Java 8 são insubstituíveis no futuro da linguagem JAVA, cujas versões posteriores irão concentrar-se apenas em melhorias de performance, sem alterações de sintaxe da linguagem.
O principal objetivo deste livro é apresentar em detalhe:
JAVA 8
C
Através dos vários exemplos resolvidos, sumários da matéria abordada e exercícios teóricos e práticos, construa e desenvolva os seus programas em Python. Para estudantes e profissionais.
Java 8 é uma linguagem de Programação Orientada pelos Objetos (POO) e assume-se como a porta de entrada principal para o que se designa por JAVA moderno. Trata-se de um conceito que pretende dar a entender que nada (de Java 5 a Java 7) foi perdido, mas que Java 8, para além de incorporar e melhorar os desenvolvimentos anteriores, introduz construções funcionais que visam uma codificação mais declarativa e simples, bem como a otimização automática do código para as atuais máquinas multi-core.
POO + Construções Funcionais
JAVA 8 POO + Construções Funcionais
F. Mário Martins Professor Associado do Departamento de Informática da Universidade do Minho (DI/UM). Criou e presidiu o Centro de Competência da JAVA do DI/UM – Sun Portugal. Desde 1980 leciona disciplinas de linguagens imperativas e funcionais, tendo introduzido a POO na UM usando Smalltalk. Nos anos 1990 iniciou o ensino de JAVA na UM, tendo lecionado em diversos cursos disciplinas das áreas de POO usando JAVA, Modelação Orientada por Objetos usando UML e Tecnologias JAVA Web. Foi presidente do Colégio de Informática da Região Norte da Ordem dos Engenheiros e avaliador de Cursos de Informática pela Ordem dos Engenheiros. Foi também membro do Júri da FCT no painel de avaliação de candidaturas a programas de Doutoramento e Pós-Doutoramento em Engenharia Informática. É autor dos livros Projetos de POO em JAVA e JAVA6 e Programação Orientada pelos Objectos, também editados pela FCA.
Distribuição
Distribuição Edição
Distribuição
Distribuição FCA – Editora de Informática, Lda.
Av. Praia da Vitória, 14 A – 1000-247 Lisboa Lidel – edições técnicas, lda Lidel – edições técnicas, lda
Tel: Lidel +351 213 511 448lda – edições técnicas, fca@fca.pt SEDE: R. D. Estefânia, 183, Dto., 1049-057 LISBOA SEDE:R/C R. D. Estefânia, 183, R/C Dto., 1049-057 LISBOA D. Estefânia, 183,/ R/C Dto., 1049-057 Internet: 21www.fca.pt 354SEDE: 14 18 R. – livrarialx@lidel.pt Revenda: 21 351 14LISBOA 43 – revenda@lidel.pt
Internet: Lidel – edições técnicas, 21 lda 354 14 18 – livrarialx@lidel.pt / Revenda: 21 351 14 43 – revenda@lidel.pt 2148 354 14 18 – livrarialx@lidel.pt / Revenda: 21 351 14 43 – revenda@lidel.pt Formação/Marketing:Internet: 21 351 14 – formacao@lidel.pt Formação/Marketing: 21 351 14 48/–marketing@lidel.pt formacao@lidel.pt / marketing@lidel.pt 211049-057 351 14 48 – formacao@lidel.pt / marketing@lidel.pt Distribuição SEDE: R. Formação/Marketing: D. Estefânia, 183, Dto., LISBOA Ens. Línguas/Exportação: 21 351 14 42R/C – depinternacional@lidel.pt Ens. Línguas/Exportação: 21 351 14 42 – depinternacional@lidel.pt Ens. Línguas/Exportação: 21 351 14/42 – depinternacional@lidel.pt Técnicas, Lda. Internet: 21 35478 1427 18 livrarialx@lidel.pt Revenda: 21 351 14 43 – revenda@lidel.pt Fax: 21 357 Lidel 78 27–– Edições 21 352 26 84 Fax: 21 357 ––21 352 26 84 Fax: 21 357 27 Dto. – 21 352 2648 84– formacao@lidel.pt Formação/Marketing: 21 – 351 14 / marketing@lidel.pt Rua D. Estefânia, 183,78 R/C 1049-057 Lisboa Línguas/Exportação: 21 351 14 42 – depinternacional@lidel.pt Tel: +351Ens. 213 511 448
Fax: 21 357 78 27 – 21 352 26 84 lidel@lidel.pt LIVRARIAS: LISBOA: Av. Praia da Vitória, – 1000-247 21 354 14 18, e-mail: LIVRARIAS: LISBOA:14 Av. Praia da LISBOA Vitória, –14Tel.: – 1000-247 LISBOA – Tel.:livrarialx@lidel.pt 21 354 14 18, e-mail: livrarialx@lidel.pt LISBOA: Av.–Praia da Vitória, 14 – 1000-247 LISBOA – Tel.: 21 354 14 18, e-mail: livrarialx@lidel.pt www.lidel.pt PORTO: R.LIVRARIAS: Damião de Góis, 452 4050-224 – Tel.: 22 557 35 10, e-mail: PORTO: R. Damião dePORTO Góis, 452 – 4050-224 PORTO – Tel.:delporto@lidel.pt 22 557 35 10, e-mail: delporto@lidel.pt PORTO: R. Damião de Góis, 452 – 4050-224 PORTO – Tel.: 22 557 35 10, e-mail: delporto@lidel.pt LIVRARIAS: LISBOA: Av. Praia da Vitória, 14 – 1000-247 LISBOA – Tel.: 21 354 14 18, e-mail: livrarialx@lidel.pt
Livraria PORTO: R. Damião de Góis, 452 – 4050-224 PORTO – Tel.: 22 557 35 10, e-mail: delporto@lidel.pt Av. Praia da Vitória, 14 A – 1000-247 Lisboa Tel: +351 213 511 448 * Fax: +351 213 522 684 livraria@lidel.pt
Copyright © FevereiroCopyright 2011 © Fevereiro 2011 Copyright © Fevereiro 2011 de Informática, Lda. Copyright © 2017, FCA – Editora FCA – Editora de Informática, Lda. FCA – Editora de Informática, Lda. Copyright © Fevereiro 2011 ISBN edição impressa: 978-972-722-838-6 FCA – Editora de Informática, Lda. 1.ª FCA edição impressa: fevereiro 2017 ISBN: 978-972-722-679-5 – Editora de Informática, Lda. ISBN: 978-972-722-679-5 ISBN: 978-972-722-679-5 ISBN: 978-972-722-679-5 Capa: José M. Ferrão – Look-Ahead Capa: José M. Ferrão – Look-Ahead Capa: José M.Mendes Ferrão – Look-Ahead Paginação: Carlos Capa: José M. – Look-Ahead Impressão e acabamento: Tipografia Rolo &Cafilesa Filhos, II––Soluções S.A. RoloGráficas, Impressão e Ferrão acabamento: Tipografia & Filhos, II – S.A. Impressão e acabamento: – Venda do Pinheiro Impressão e acabamento: Tipografia Rolo & Filhos, Lda. II – S.A. Impressão e acabamento: Tipografia Rolo & Filhos, II – S.A. Depósito Legal n.º 421721/17 Depósito Legal N.º ……… Depósito Legal N.º ……… Depósito Legal N.º ……… Capa: José Legal Manuel Depósito N.ºReis ………
Ilustração da capa: Miguel Montenegro
FCA – Editora Marcas Registadas de de Informática, Lda. de Informática, Lda. Marcas Registadas de FCA – Editora Marcas Registadas Marcas Registadas deFCA FCAFCA de Lda. Marcas de – Editora Editora deInformática, Informática, Lda. – Registadas de – Editora de Informática, Lda. ®
® ®
® ®
®
® ®®
®
®®
Este pictograma merece uma explicação. O seu propósito alertar leitor paraéoaalertar ameaça pictograma merece uma explicação. O seuo propósito o leitor para aque ameaça que EsteEste pictograma merece uma explicação. Oé seu propósito é alertar leitor para aque ameaça Este da pictograma merece uma explicação. seu propósito éealertar o leitoropara a ameaça que representa para o futuro escrita, nomeadamente na daOedição técnica universitária, Todos os nossos livros passam por controlo deárea qualidade, noárea entanto aconselhamos consultaeperiódica do o representa para oum futuro da escrita, nomeadamente na da área edição técnica universitária, o representa para origoroso futuro da escrita, nomeadamente na da ediçãoeatécnica universitária, representa para o futuro da escrita, nomeadamente na área da edição técnica e universitária, o desenvolvimento da fotocópia. desenvolvimento massivo da fotocópia. desenvolvimento massivo da fotocópia.correções. nosso site (www.fca.pt) para fazermassivo o download de eventuais desenvolvimento massivo da fotocópia. O Código doestabelece Direito de Autor estabelece que é por crime por lei, a fotocópia sem autorização O Código do Direito de Autor queAutor é crime punido a fotocópia sem autorização O Código do Direito de estabelece quelei, épunido crime punido por lei, a fotocópia sem autorização Oproprietários CódigoNo dodo Direito de Autor estabelece que égeneralizou-se crime punido por lei, a fotocópia sem autorização dos copyright. No entanto, esta prática sobretudo no ensino superior, dos do copyright. entanto, esta prática generalizou-se sobretudo no ensino superior, dos proprietários do copyright. No entanto, esta prática generalizou-se sobretudo no ensino superior, Nãoproprietários nos responsabilizamos por desatualizações das hiperligações presentes nesta obra, que foram verificadas à data de dos proprietários do copyright. Nonalivros entanto, esta prática generalizou-se sobretudo no ensino provocando umauma queda substancial compra de livros técnicos. Assim, num paísaem a emsuperior, provocando queda substancial na compra de técnicos. Assim, numtécnicos. país em que provocando queda substancial na compra de livros Assim, numque país que a publicação dauma mesma. provocando na compra de livros técnicos. Assim, num país em que a literatura técnica uma é tão queda escassa, substancial os autores não sentem motivação para criar obras inéditas e fazêliteratura técnica é tão escassa, os autores sentem para criarmotivação obras inéditas e criar fazê-obras inéditas e fazêliteratura técnica é tãonão escassa, osmotivação autores não sentem para -lasliteratura publicar, ficando os impossibilitados de não ter bibliografia em português. técnica é leitores tão escassa, os autores sentem motivação para criar obras inéditas e fazê-las publicar, ficando os leitores impossibilitados de ter bibliografia em português. -las publicar, ficando os leitores impossibilitados de ter bibliografia em português. Os nomes comerciais referenciados neste têm patente registada portanto, quelivro expressamente proibida de a reprodução, no em todoportuguês. ou em parte, da Lembramos publicar, ficando osé leitores impossibilitados ter bibliografia Lembramos portanto, que é expressamente proibida a reprodução, no todo ou em parte, Lembramos portanto, que é expressamente proibida a reprodução, no da todo ou em parte, da -las presente obra sem autorização quedaé editora. expressamente proibida a reprodução, no todo ou em parte, da Lembramos presente obra sem autorização daportanto, editora. presente obra sem autorização da editora. presente obra sem autorização da editora. Reservados todos os direitos. Esta publicação não pode ser reproduzida, nem transmitida, no todo ou em parte, por qualquer processo eletrónico, mecânico, fotocópia, digitalização, gravação, sistema de armazenamento e disponibilização de informação, sítio Web, blogue ou outros, sem prévia autorização escrita da Editora, exceto o permitido pelo CDADC, em termos de cópia privada pela AGECOP – Associação para a Gestão da Cópia Privada, através do pagamento das respetivas taxas.
ÍNDICE GERAL
SOBRE O LIVRO 1
XIII
PARADIGMA DA PROGRAMAÇÃO ORIENTADA PELOS OBJETOS
1
1.1 INTRODUÇÃO...................................................................................................................................................................... 1 1.1.1
VIA DA SIMULAÇÃO........................................................................................................................................ 2
1.1.2
VIA DA ENGENHARIA DE SOFTWARE.................................................................................................... 3
1.1.3
LINGUAGENS ESTRUTURADAS.................................................................................................................. 4
1.1.4
LINGUAGENS MODULARES.......................................................................................................................... 6
1.2
ABSTRAÇÃO DE DADOS E DATA HIDING.............................................................................................................. 8
1.3
O QUE É UM OBJETO?................................................................................................................................................... 13
1.4
ENCAPSULAMENTO: PROPRIEDADE FUNDAMENTAL.................................................................................... 14
1.5 MENSAGENS....................................................................................................................................................................... 15 1.6
2
OBJETOS EM POO: INSTÂNCIAS E CLASSES...................................................................................................... 19
JAVA: TECNOLOGIA E INTRODUÇÃO À LINGUAGEM
23
2.1 INTRODUÇÃO...................................................................................................................................................................... 23 2.2 GÉNESE DA TECNOLOGIA JAVA............................................................................................................................... 23 2.2.1
JAVA 5................................................................................................................................................................... 26
2.2.2 JAVA 8................................................................................................................................................................... 27 2.3 O QUE É A TECNOLOGIA JAVA.................................................................................................................................. 27 2.4 LINGUAGEM JAVA: CARACTERÍSTICAS................................................................................................................. 32 2.4.1 INTRODUÇÃO...................................................................................................................................................... 32 2.4.2 NÍVEL DOS TIPOS PRIMITIVOS................................................................................................................... 33 2.4.3 DECLARAÇÕES DE VARIÁVEIS E INICIALIZAÇÃO............................................................................. 34 2.4.4 DECLARAÇÕES DE CONSTANTES............................................................................................................. 35 2.4.5 CONVERSÃO ENTRE TIPOS: CASTING.................................................................................................... 36 2.4.6 COMENTÁRIOS EM JAVA.............................................................................................................................. 37 2.4.7 CONJUNTO DE OPERADORES..................................................................................................................... 37 2.4.8 INSTRUÇÕES, ESTRUTURAS DE CONTROLO E DIRETIVAS........................................................... 40 2.4.8.1
if/else............................................................................................................................................ 40
2.4.8.2 switch.............................................................................................................................................. 41 2.4.8.3 for....................................................................................................................................................... 42 2.4.8.4 while................................................................................................................................................. 43 2.4.8.5 do/while......................................................................................................................................... 44 2.4.9 STRINGS................................................................................................................................................................ 45 2.4.10 I/O SIMPLES........................................................................................................................................................ 46 2.4.10.1
SAÍDA FORMATADA: printf()............................................................................................ 46
2.4.10.2 LEITURAS COM Scanner......................................................................................................... 47 2.4.11 TIPOS REFERENCIADOS: OBJETOS E ARRAYS.................................................................................. 48 2.4.11.1
ARRAYS............................................................................................................................................ 50
2.4.11.2
ACESSO AOS ELEMENTOS DE UM ARRAY...................................................................... 51 © FCA – EDITORA DE INFORMÁTICA
V
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS
2.4.11.3 CICLO for COM ARRAYS.......................................................................................................... 51 2.4.11.4 CICLO For(each) COM ARRAYS.......................................................................................... 52 2.4.12 ESTRUTURA DE UM PROGRAMA.............................................................................................................. 53 2.5 CRIAÇÃO DO AMBIENTE JAVA.................................................................................................................................. 56
3
CLASSES, INSTÂNCIAS E METODOLOGIA ORIENTADA PELOS OBJETOS 3.1
57
DEFINIÇÃO DE CLASSE.................................................................................................................................................. 57
3.2 CRIAÇÃO DE CLASSES: INTRODUÇÃO................................................................................................................... 59 3.2.1 CLASSE Ponto: REQUISITOS INICIAIS.................................................................................................... 59 3.2.2 DEFINIÇÃO DA ESTRUTURA......................................................................................................................... 60 3.2.3 DEFINIÇÃO DO COMPORTAMENTO: CONSTRUTORES..................................................................... 60 3.2.4 DEFINIÇÃO DO COMPORTAMENTO: MÉTODOS DE INSTÂNCIA.................................................. 62 3.2.5 REFERÊNCIA this........................................................................................................................................... 66 3.2.6 PACKAGES E IMPORTAÇÃO DE CLASSES............................................................................................. 68 3.2.7 DEFINIÇÃO ATUAL DA CLASSE Ponto................................................................................................... 70 3.2.8 REGRAS DE ACESSIBILIDADE A UMA CLASSE.................................................................................. 71 3.2.9 REGRAS DE ACESSO A VARIÁVEIS E MÉTODOS DE INSTÂNCIA.............................................. 72 3.2.10 DEFINIÇÃO FINAL DA CLASSE Ponto.................................................................................................... 73 3.2.11 COMPILAÇÃO E TESTE DA CLASSE Ponto.......................................................................................... 74 3.2.12 MÉTODOS COMPLEMENTARES ÚTEIS.................................................................................................... 75 3.2.13 SOBRECARGA DE MÉTODOS (OVERLOADING)................................................................................... 77 3.2.14 MÉTODOS COM NÚMERO VARIÁVEL DE PARÂMETROS (VARARGS)..................................... 78 3.3 PARADIGMA IMPERATIVO vs. ORIENTAÇÃO PELOS OBJETOS: METODOLOGIA ORIENTADA PELOS OBJETOS............................................................................................................................................................... 79 3.4 CLASSES SIMPLES, OBJETOS E COMPORTAMENTO...................................................................................... 82 3.5 COMPOSIÇÃO NA DEFINIÇÃO DE CLASSES........................................................................................................ 86 3.5.1 MÉTODOS get() E set() E ENCAPSULAMENTO............................................................................. 88 3.5.2 ENCAPSULAMENTO E CLONE..................................................................................................................... 93 3.5.2.1
CLONE PREDEFINIDO DE JAVA.............................................................................................. 95
3.5.2.2 IMPLEMENTAÇÃO CORRETA DO MÉTODO clone()................................................... 96 3.5.3 MÉTODOS equals(Object o) E toString()............................................................................... 98 3.6 EXEMPLO: CLASSE Segmento.................................................................................................................................. 100 3.7 EXEMPLO: CARTÃO DE CRÉDITO ECARD.............................................................................................................. 103 3.7.1
MÉTODOS PARCIAIS E PRÉ-CONDIÇÕES............................................................................................... 104
3.8 MÉTODOS E VARIÁVEIS DE CLASSE...................................................................................................................... 108 3.9 FACTORY METHODS....................................................................................................................................................... 112 3.10 IMPORTAÇÃO ESTÁTICA............................................................................................................................................... 114 3.11 CLASSES NÃO INSTANCIÁVEIS................................................................................................................................. 115 3.12 CLASSES WRAPPER: Integer, Double E OUTRAS...................................................................................... 117 3.13 ANNOTATIONS................................................................................................................................................................... 118
4 IDE PARA JAVA: BLUEJ, NETBEANS E ECLIPSE
119
4.1 INTRODUÇÃO...................................................................................................................................................................... 119 4.2 BLUEJ..................................................................................................................................................................................... 120 4.2.1
JANELA DE TRABALHO................................................................................................................................. 120
4.2.2 PROJECT................................................................................................................................................................ 122 4.2.3 CRIAÇÃO DE UMA NOVA CLASSE............................................................................................................. 123 VI
© FCA – EDITORA DE INFORMÁTICA
ÍNDICE GERAL 4.2.4 CRIAÇÃO DE INSTÂNCIAS............................................................................................................................. 126 4.2.5 INTERAÇÃO COM AS INSTÂNCIAS............................................................................................................ 130 4.2.6 TOOLS.................................................................................................................................................................... 132 4.2.7 VIEW........................................................................................................................................................................ 132 4.3 NETBEANS, ECLIPSE E INTELLIJ............................................................................................................................... 133
5 HIERARQUIA DE CLASSES E HERANÇA
137
5.1 INTRODUÇÃO...................................................................................................................................................................... 137 5.2 HIERARQUIA DE CLASSES........................................................................................................................................... 140 5.3 MECANISMO DE HERANÇA......................................................................................................................................... 143 5.3.1
ALGORITMO DE PROCURA DE MÉTODOS............................................................................................. 144
5.3.2 SOBREPOSIÇÃO DE MÉTODOS E VARIÁVEIS: REFERÊNCIAS this E super.................................................................................................................................... 145 5.3.3 MODIFICADORES E REDEFINIÇÃO DE MÉTODOS.............................................................................. 150 5.3.4 CLASSES SEM SUBCLASSES...................................................................................................................... 151 5.3.5 SUBCLASSES E CONSTRUTORES: UTILIZAÇÃO DE this() E super()........................................................................................................................ 151 5.3.6 TOPO DA HIERARQUIA: CLASSE Object............................................................................................. 154 5.4 CRIAÇÃO DE CLASSES VIA HERANÇA: EXEMPLOS......................................................................................... 157 5.4.1
EXEMPLO 1: SUBCLASSES DE Ponto2D................................................................................................. 157 5.4.1.1 CLASSE Pixel................................................................................................................................. 158 5.4.1.2 CLASSE Ponto3D............................................................................................................................ 160
5.4.2 EXEMPLO 2: ELETRODOMÉSTICOS.......................................................................................................... 161 5.5 COMPATIBILIDADE ENTRE CLASSES E SUBCLASSES.................................................................................... 167 5.5.1
PRINCÍPIO DA SUBSTITUIÇÃO..................................................................................................................... 167
5.5.2 TIPOS ESTÁTICOS E TIPOS DINÂMICOS................................................................................................. 170 5.5.3 PROCURA DINÂMICA DE MÉTODOS (DYNAMIC METHOD LOOKUP)......................................... 173 5.5.4 TIPOS COVARIANTES E REDEFINIÇÃO DE MÉTODOS..................................................................... 178 5.6 PROGRAMAÇÃO GENÉRICA VIA POLIMORFISMO........................................................................................... 179 5.7 PROGRAMAÇÃO INCREMENTAL............................................................................................................................... 181 5.8 O PROBLEMA DA CLASSIFICAÇÃO: CLASSES NOVAS COMO SUBCLASSES DE Object............ 181 5.9 CRIAÇÃO DE CLASSES: REGRAS ANOTADAS.................................................................................................... 182
6
CLASSES ABSTRATAS E POLIMORFISMO 6.1
187
INTRODUÇÃO ÀS CLASSES ABSTRATAS............................................................................................................. 187
6.2 UTILIZAÇÃO DE CLASSES ABSTRATAS................................................................................................................ 191 6.3 CLASSES ABSTRATAS E VARIÁVEIS DE INSTÂNCIA...................................................................................... 195 6.4 EXEMPLO FINAL: CABAZ.............................................................................................................................................. 197 6.5 CONSIDERAÇÕES FINAIS.............................................................................................................................................. 202
7
INTERFACES DE JAVA
205
7.1 INTRODUÇÃO...................................................................................................................................................................... 205 7.2 INTERFACES DE JAVA: DECLARAÇÃO................................................................................................................... 207 7.3 HIERARQUIA DE INTERFACES: INTRODUÇÃO..................................................................................................... 209 7.4 IMPLEMENTAÇÃO DE INTERFACES......................................................................................................................... 211 7.5 INTERFACES CONSTANTES E IMPORTAÇÃO ESTÁTICA................................................................................. 215 © FCA – EDITORA DE INFORMÁTICA
VII
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS
7.6 HIERARQUIA DE INTERFACES: REGRAS DE REDEFINIÇÃO.......................................................................... 216 7.7 DEFAULT METHODS........................................................................................................................................................ 220 7.7.1
DEFAULT METHODS: SÍNTESE.................................................................................................................... 224
7.8 MÉTODOS DE CLASSE EM INTERFACES............................................................................................................... 225 7.9 CLASSES ABSTRATAS VS. INTERFACES.............................................................................................................. 227 7.10 INTERFACES PREDEFINIDAS DE JAVA................................................................................................................... 230 7.10.1 INTERFACE Serializable........................................................................................................................ 230 7.10.2 INTERFACES PARAMETRIZADAS: INTRODUÇÃO............................................................................. 230 7.11 INTERFACES FUNCIONAIS............................................................................................................................................ 232 7.12 INTERFACES PARAMETRIZADAS DE COLEÇÕES............................................................................................. 234 7.13 CONSTRUÇÕES ÚTEIS COM INTERFACES E CLASSES UTILITÁRIAS........................................................ 235
8 EXCEÇÕES 237 8.1 INTRODUÇÃO...................................................................................................................................................................... 237 8.2 O QUE É UMA EXCEÇÃO?............................................................................................................................................. 238 8.3 TRATAMENTO DE EXCEÇÕES: try E catch....................................................................................................... 241 8.3.1
EXEMPLOS DE UTILIZAÇÃO......................................................................................................................... 243
8.4 LANÇAMENTO DE EXCEÇÕES: throw E throws............................................................................................. 251 8.4.1
EXEMPLO: EQUIPA ROBUSTA..................................................................................................................... 252
8.4.2 EXEMPLO: STACK ROBUSTA........................................................................................................................ 254 8.4.3 RELANÇAMENTO DE EXCEÇÕES................................................................................................................ 255 8.5 REDEFINIÇÃO DE MÉTODOS COM throws......................................................................................................... 257 8.6 EXCEÇÕES EM CONSTRUTORES................................................................................................................................ 258 8.7 CLASSES DE EXCEÇÃO DE JAVA.............................................................................................................................. 259 8.8 TRY WITH RESOURCES.................................................................................................................................................. 262 8.9 EXCEÇÕES MULTI-CATCH.............................................................................................................................................. 263
9 O NOVO PACKAGE java.time 265 9.1 INTRODUÇÃO...................................................................................................................................................................... 265 9.2 LocalDate, LocalDateTime E LocalTime................................................................................................... 268 9.3 ARQUITETURA DE java.time.................................................................................................................................. 271 9.4 NORMALIZAÇÃO DOS NOMES DOS MÉTODOS EM java.time............................................................... 273 9.5 Period.................................................................................................................................................................................. 275 9.6 Duration............................................................................................................................................................................ 277 9.7 Instant............................................................................................................................................................................... 278 9.8 Year, YearMonth E MonthDay................................................................................................................................ 279 9.9 ChronoField.................................................................................................................................................................... 281 9.10 IsoFields.......................................................................................................................................................................... 283 9.11 ChronoUnit....................................................................................................................................................................... 284 9.12 ZoneId, ZonedDateTime E ZoneOffset.......................................................................................................... 286 9.13 Clock.................................................................................................................................................................................... 290 9.14 MEDIÇÃO DE TEMPOS DE COMPUTAÇÃO............................................................................................................ 290 9.15 TemporalAdjusters................................................................................................................................................... 291 9.16 FORMATAÇÃO E PARSING........................................................................................................................................... 293 9.17 COMPATIBILIDADE COM java.util.Calendar E java.util.Date.................................................. 297 9.18 CONCLUSÃO........................................................................................................................................................................ 298 VIII
© FCA – EDITORA DE INFORMÁTICA
ÍNDICE GERAL 10 CONSTRUÇÕES FUNCIONAIS DE JAVA
299
10.1 ENQUADRAMENTO: QUAL O PROBLEMA?.......................................................................................................... 299 10.2 ENCAPSULAMENTO DE COMPORTAMENTO....................................................................................................... 300 10.3 MÉTODOS VS. FUNÇÕES.............................................................................................................................................. 303 10.4 EXPRESSÕES LAMBDA................................................................................................................................................. 305 10.4.1 NOVAS FORMAS DE REFERÊNCIA DE MÉTODOS............................................................................. 307 10.5 INTERFACES FUNCIONAIS............................................................................................................................................ 309 10.5.1 BIBLIOTECA java.util.function....................................................................................................... 311 10.5.2 Predicate<T>................................................................................................................................................. 315 10.5.3 Function<T, R>............................................................................................................................................ 319 10.5.3.1
BiFunction<T, U, R>........................................................................................................... 323
10.5.4 Supplier<T>.................................................................................................................................................... 323 10.5.5 Consumer<T>.................................................................................................................................................... 324 10.5.6 UnaryOperator<T>...................................................................................................................................... 324 10.5.7 BinaryOperator<T>................................................................................................................................... 325 10.5.8 LAMBDAS E STREAMS: IDEIAS BÁSICAS............................................................................................. 326 10.5.9 DEFAULT METHODS EM INTERFACES FUNCIONAIS......................................................................... 327 10.5.9.1 DEFAULT METHODS DE Predicate<T>.......................................................................... 328 10.5.9.2 DEFAULT METHODS DE Function<T, R> E COMPOSIÇÃO FUNCIONAL........ 329 10.5.9.3 DEFAULT METHODS E HERANÇA MÚLTIPLA................................................................... 331 10.5.10 STATIC METHODS EM INTERFACES FUNCIONAIS.............................................................................. 331 10.5.11 COMPOSIÇÃO DE FUNÇÕES: SÍNTESE.................................................................................................... 332 10.5.12 APLICAÇÃO PARCIAL DE UMA FUNÇÃO: CURRYING....................................................................... 335 10.5.13 REGRAS DE SCOPE DE UMA EXPRESSÃO LAMBDA OU FUNÇÃO............................................ 337
11
COLEÇÕES DE JCF: INTRODUÇÃO
343
11.1 INTRODUÇÃO...................................................................................................................................................................... 343 11.1.1
OBJETIVOS DO CAPÍTULO............................................................................................................................ 344
11.1.2
COLEÇÕES DE JAVA: JCF.............................................................................................................................. 344
11.1.3
JCF 5....................................................................................................................................................................... 346
11.1.4
JCF 8....................................................................................................................................................................... 348
11.2 TIPOS GENÉRICOS............................................................................................................................................................ 348 11.3 INTERFACE Iterable<E>........................................................................................................................................... 350 11.3.1
ITERADORES ATIVOS E ITERADORES PASSIVOS............................................................................ 350
11.4 INTERFACE Collection<E>..................................................................................................................................... 351 11.5 INTERFACE List<E>...................................................................................................................................................... 352 11.5.1 CLASSE ArrayList<E>................................................................................................................................ 354 11.5.2 DIAMOND NOTATION....................................................................................................................................... 357 11.5.3 ITERAÇÃO EXTERNA DE COLEÇÕES........................................................................................................ 358 11.5.3.1 ITERADOR FOREACH.................................................................................................................. 358 11.5.3.2 ITERADOR Iterator<E>......................................................................................................... 360 11.5.3.3 ITERADOR ListIterator <E>........................................................................................... 362 11.5.4 BULK OPERATIONS COM List<E>........................................................................................................... 363 11.6 EXEMPLO: LISTAS DE NOMES.................................................................................................................................... 364 11.7 IMPLEMENTAÇÃO DE COLEÇÕES............................................................................................................................. 365 11.8 CLONE DE COLEÇÕES..................................................................................................................................................... 371 © FCA – EDITORA DE INFORMÁTICA
IX
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS
11.9 INTERFACE Set<E>......................................................................................................................................................... 371 11.9.1
HashSet<E>....................................................................................................................................................... 373
11.10 BOXING E UNBOXING EM COLEÇÕES...................................................................................................................... 373 11.11 TreeSet<E>....................................................................................................................................................................... 374 11.11.1
TreeSet<E> E Comparable<T>............................................................................................................. 376
11.11.2 TreeSet<E> E Comparator<E> EM JAVA 7..................................................................................... 377 11.11.3 TreeSet<E>, Comparator<E> E LAMBDAS DE JAVA 8............................................................. 379 11.12 COLEÇÕES E POLIMORFISMO: EXEMPLO............................................................................................................. 380 11.13 NÃO COVARIÂNCIA DAS COLEÇÕES....................................................................................................................... 385 11.14 WILDCARDS: PARTE I..................................................................................................................................................... 386 11.15 WILDCARDS: PARTE II.................................................................................................................................................... 392 11.16 INTERFACE Map<K, V>................................................................................................................................................ 395 11.17 HashMap<K, V>.............................................................................................................................................................. 397 11.17.1
ITERADORES DE Map<K, V>..................................................................................................................... 399
11.17.2 MODIFICAÇÃO DE PARES (k,v)............................................................................................................... 400 11.17.3 BULK OPERATIONS SOBRE MAPS............................................................................................................ 403 11.17.4 hashCode() E equals()............................................................................................................................ 404 11.18 TreeMap<K, V>.............................................................................................................................................................. 405 11.18.1 TreeMap<K, V>, Comparator<K> E LAMBDAS............................................................................ 407 11.18.2 NavigableMap................................................................................................................................................. 409 11.18.3 MODIFICAÇÃO DAS CHAVES DE UM MAP............................................................................................ 410 11.19 FILAS DE TIPO E: Queue<E>...................................................................................................................................... 411 11.20 TIPOS ENUMERADOS..................................................................................................................................................... 411 11.20.1 TIPOS ENUMERADOS: DECLARAÇÃO..................................................................................................... 414 11.20.2 MÉTODOS PREDEFINIDOS............................................................................................................................ 415 11.20.3 CLASSE EnumSet<E>..................................................................................................................................... 418 11.20.4 ATRIBUTOS E MÉTODOS EM TIPOS ENUMERADOS........................................................................ 421 11.20.5 CLASSE EnumMap<K, V>............................................................................................................................ 424 11.20.6 PROPRIEDADES ADICIONAIS...................................................................................................................... 425
12 STREAMS E PIPELINES 427 12.1 O QUE SÃO STREAMS?................................................................................................................................................. 427 12.2 STREAMS PRIMITIVAS................................................................................................................................................... 430 12.2.1 AS STREAMS NÃO SÃO REUTILIZÁVEIS............................................................................................... 434 12.2.2 CRIAÇÃO DE STREAMS.................................................................................................................................. 437 12.2.3 OPERAÇÕES INTERMÉDIAS E TERMINAIS: DEFINIÇÃO.................................................................. 440 12.3 SEMÂNTICA DAS OPERAÇÕES INTERMÉDIAS E TERMINAIS..................................................................... 444 12.3.1 filter..................................................................................................................................................................... 446 12.3.2 map.......................................................................................................................................................................... 447 12.3.3 forEach................................................................................................................................................................ 448 12.3.4 forEachOrdered............................................................................................................................................ 448 12.3.5 reduce.................................................................................................................................................................. 449 12.3.6 mapToObj E boxed......................................................................................................................................... 451 12.3.7 collect................................................................................................................................................................ 452 12.3.8 allMatch, anyMatch E noneMatch.................................................................................................... 454 12.3.9 sorted.................................................................................................................................................................. 455 12.3.10 limit..................................................................................................................................................................... 455 X
© FCA – EDITORA DE INFORMÁTICA
ÍNDICE GERAL 12.3.11 distinct............................................................................................................................................................. 456 12.3.12 findFirst E findAny...................................................................................................................................... 456
12.3.13 skip........................................................................................................................................................................ 457 12.3.14 toArray............................................................................................................................................................... 458 12.3.15 summaryStatistics................................................................................................................................... 458 12.3.16 flatMap.................................................................................................................................................................. 459
12.3.17 peek........................................................................................................................................................................ 461 12.4 STREAMS E COLEÇÕES: INTRODUÇÃO.................................................................................................................. 464 12.4.1 CLASSE Stream<T> E OS SEUS MÉTODOS........................................................................................ 467 12.4.2 ALGUNS EXEMPLOS COM Stream<T>.................................................................................................. 468 12.4.3 STREAMS E Map<K, V>............................................................................................................................... 476 12.4.4 Collectors EM DETALHE.......................................................................................................................... 478 12.4.4.1 MÉTODOS averaging, summarizing, summing E counting.......................... 479 12.4.4.2 MÉTODO joining....................................................................................................................... 480 12.4.4.3 MÉTODO groupingBy.............................................................................................................. 481 12.4.4.4 MÉTODO partitioningBy................................................................................................... 484 12.4.4.5 MÉTODOS toX............................................................................................................................... 485 12.4.4.6 MÉTODO collectingAndThen.......................................................................................... 489 12.4.4.7 PROGRAMAÇÃO DE NOVOS COLLECTORS...................................................................... 490 12.4.4.8 COMPOSIÇÃO DE COLLECTORS............................................................................................. 493 12.4.4.9 ARRAYS E STREAMS.................................................................................................................. 494 12.4.5 FUNCIONAMENTO REAL DA PIPELINE.................................................................................................... 496 12.4.6 OPERAÇÕES SOBRE STREAMS: SÍNTESE DE CATEGORIAS E FUNCIONAMENTO............ 501 12.4.6.1
STATEFUL OPERATIONS (OPERAÇÕES COM ESTADO INTERNO).......................... 502
12.4.6.2 SHORT-CIRCUITING OPERATIONS......................................................................................... 505 12.4.7 ORDEM DE ENCONTRO (ENCOUNTER ORDER).................................................................................... 508 12.4.8 STREAMS PARALELAS.................................................................................................................................. 510
13 COLEÇÕES E STREAMS: NOVO MODELO DE PROGRAMAÇÃO
515
13.1 INTRODUÇÃO...................................................................................................................................................................... 515 13.2 PROJETO: HIPERMERCADO......................................................................................................................................... 516 13.2.1 CONTAGENS E ESTATÍSTICAS..................................................................................................................... 517 13.2.2 CLASSIFICAÇÕES, SÍNTESES E AGRUPAMENTOS............................................................................ 520 13.2.3 PARES, TRIPLOS, ORDENAÇÕES E SELEÇÕES................................................................................... 522 13.2.4 TRANSFORMAÇÃO DE Map<K, V> EM List<ParKV>................................................................. 526 13.2.5 OPERAÇÕES BULK COM STREAMS.......................................................................................................... 528 13.2.6 QUESTÕES SOBRE PERFORMANCE........................................................................................................ 530 13.2.7 ESTRUTURAÇÃO DO CÓDIGO: NOTA FINAL......................................................................................... 535
14 STREAMS DE I/O E FILES 537 14.1 INTRODUÇÃO...................................................................................................................................................................... 537 14.2 I/O BÁSICO.......................................................................................................................................................................... 543 14.3 I/O DE LINHAS DE TEXTO............................................................................................................................................ 544 14.3.1 CLASSE Scanner E I/O BÁSICO............................................................................................................... 545 14.4 MÉTODO split() E PARSING DE LINHAS DE TEXTO..................................................................................... 550 14.5 REGEX, PATTERN E EXPRESSÕES REGULARES................................................................................................ 557 © FCA – EDITORA DE INFORMÁTICA
XI
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS
14.6 STREAMS DE CARATERES: LEITURA E ESCRITA.............................................................................................. 560 14.6.1 PRINCIPAIS STREAMS DE LEITURA DE CARATERES....................................................................... 564 14.6.2 PRINCIPAIS STREAMS DE ESCRITA DE CARATERES....................................................................... 568 14.6.2.1 CLASSE BufferedWriter..................................................................................................... 568 14.6.2.2 CLASSE FileWriter................................................................................................................. 568 14.6.2.3 CLASSE PrintWriter.............................................................................................................. 568 14.7 STREAMS DE BYTES...................................................................................................................................................... 571 14.8 STREAMS DE OBJETOS................................................................................................................................................ 572 14.9 CLASSES NÃO STREAM DE java.io E DE java.nio.............................................................................................. 573 14.9.1 CLASSE java.nio.file.Path................................................................................................................... 574
14.9.2 CLASSE java.nio.file.Files................................................................................................................ 576
14.10 FILES E GLOBBING........................................................................................................................................................... 579 14.10.1 GLOB EM java.nio........................................................................................................................................ 579
ÍNDICE REMISSIVO
XII
© FCA – EDITORA DE INFORMÁTICA
583
SOBRE O LIVRO
As modificações introduzidas pela versão Java 8 (março de 2014) são as maiores da história da linguagem JAVA, combinando alterações coordenadas da linguagem, das suas bibliotecas e do código final gerado para a máquina virtual. Numa era em que é necessário processar quantidades massivas de dados e tirar o máximo partido de máquinas com quantidades igualmente massivas de processadores, JAVA mantém o paradigma da Programação Orientada pelos Objetos (POO), como modelo fundamental de conceção, mas acrescenta-lhe construções oriundas do paradigma funcional, mais aptas a lidar com funções anónimas (lambdas), streams de dados e paralelismo. Java 8, com todas as suas novas construções funcionais e não só, é a porta de entrada crucial para aquilo que os arquitetos de JAVA, os programadores, os autores, enfim, todos os que seguiram o processo evolutivo de JAVA, nos quais me incluo, designam por JAVA moderno. JAVA moderno é um conceito que pretende dar a entender, entre outras coisas, que nada entre Java 5 e Java 7 foi perdido, mas que Java 8, para além de incorporar e melhorar os desenvolvimentos anteriores, deu um passo gigante, que durará muitos anos, ao incorporar construções típicas das linguagens funcionais. JAVA torna-se claramente uma linguagem híbrida entre a orientada pelos objetos (OO) e a funcional, permitindo uma programação muito mais clara e declarativa, bem como a otimização automática do código para máquinas de múltiplos processadores, sem intervenção do programador. Sendo Java 8 retrocompatível, para que este livro seja completo, deve abordar o paradigma da POO e as suas caraterísticas, todas as construções linguísticas de JAVA, quer as de base quer as de versões anteriores, que foram preservadas e até melhoradas, e, naturalmente, as novidades de Java 8, como as construções funcionais (funções e expressões lambda), as interfaces funcionais, as streams de dados e todas as novas bibliotecas. Assim, esta obra tem como objetivos: ■■
■■
Apresentar em detalhe os conceitos e as construções intrínsecas ao paradigma da POO: ■■
Regras e metodologia de conceção e desenvolvimento de aplicações OO;
■■
Classes e instâncias; objetos, mensagens, métodos e encapsulamento;
■■
Hierarquia de classes e herança; classes abstratas e polimorfismo;
■■
Programação genérica e extensível: regras e técnicas.
Apresentar as construções não funcionais fundamentais de JAVA: ■■
JAVA básico: tipos primitivos, arrays e estruturas de controlo;
■■
Regras para a criação de classes completas; encapsulamento e cloning;
■■
Interfaces e respetiva hierarquia; interfaces como tipos;
■■
Exceções e segurança; © FCA – EDITORA DE INFORMÁTICA
XIII
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS
■■
■■
O novo package java.time de Java 8; instantes, durações, períodos, datas, fusos, etc.;
■■
Coleções de JAVA: estudo de Java Collections Framework (JCF);
■■
Tipos genéricos e wildcards; covariância das coleções;
■■
Streams de I/O, files, paths; java.io e java.nio; Regex, Pattern, Matcher; formatação e validação de dados.
Apresentar as novas construções funcionais de Java 8: ■■
Expressões lambda (lambdas); funções anónimas;
■■
Funções e seus tipos (package java.util.function);
■■
Interfaces funcionais; métodos default; factory methods;
■■
Streams de dados sequenciais, paralelas e infinitas (package java.util.stream);
■■
Streams primitivas e tipo Stream<T>;
■■
Pipelines de programação com streams e lambdas;
■■
Novo modelo de programação de coleções com streams e pipelines.
Ao longo do livro são apresentados vários exemplos de todas estas construções e os resultados das suas execuções. Esta é uma obra extensa mas completa, com vários tipos de destinatários em função dos seus conhecimentos atuais de JAVA. Pode ser usado por: iniciados quer em POO, quer em JAVA; quem já sabe o paradigma da POO mas pretende agora estudar JAVA; e todos aqueles que já conhecem a linguagem até Java 7 e querem agora descobrir as maravilhas de Java 8. Boa leitura e bom estudo!
F. Mário Martins
XIV
© FCA – EDITORA DE INFORMÁTICA
9 O NOVO PACKAGE java.time TÓPICOS ■■ ■■ ■■
A nova API Date-Time; Referências UTC e Epoch; LocalTime, LocalDate e LocalDateTime;
■■ ■■ ■■
Instant, Period e Duration; ChronoUnit e ChronoField; Fusos horários: TimeZone e Offset.
9.1 INTRODUÇÃO A nova API Date-Time de Java 8 para datas, tempos, períodos, durações, instantes e fusos horários (JSR-310) está contida no package principal java.time e em quatro outros packages designados por java.time.chrono, java.time.format, java.time.temporal e java.time.zone, que apresentaremos em síntese na Tabela 9.1, depois de introduzirmos alguns conceitos fundamentais. O package principal, java.time, é retrocompatível com as antigas classes de java.util, designadamente, Calendar, GregorianCalendar, Date e TimeZone, mas torna estas antigas classes obsoletas. Só por si, java.time propõe 15 novas classes distintas e muitos métodos de classe e de instância que vêm substituir as antigas classes para datas e tempos. Esta nova biblioteca de Java 8 segue muitas das ideias do Projeto Joda-Time, que havia sido desenvolvido para versões anteriores a Java 8. Os utilizadores da biblioteca Joda-Time são agora convidados a migrar para java.time (JSR-310). É usado como formato standard para calendários o formato designado por sistema ISO-8601:2004, que é uma formalização proléptica do calendário Gregoriano designada por Calendário Gregoriano Proléptico. Tal significa que este calendário é correto mesmo para anos anteriores à sua criação (Papa Gregório XIII em 1582) e trata bem o problema dos 10 dias que deixaram de existir na Terra na transição entre o calendário Juliano (Júlio César, 46 a.C.) e o calendário Gregoriano. Este é o formato de calendário usado atualmente em SQL, em JDBC e na maioria de outros sistemas de gestão de bases de dados consistindo num verdadeiro standard universal. São igualmente suportados diversos calendários menos comuns, tais como o Chinês e o Thai Budista. As classes definidas neste package representam os principais conceitos relacionados com datas e tempos, designadamente datas, tempos, períodos, durações e instantes, e ainda com tempo local ou com zona horária ou fuso horário (time zone).
© FCA – EDITORA DE INFORMÁTICA
265
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS Cada instância das várias classes de data e tempo são compostas por múltiplos campos que são tornados disponíveis através dos métodos get das suas API. As classes desenvolvidas no package java.time podem ser classificadas por grupos de funcionalidade, o que facilita a sua compreensão geral. Existem classes que criam objetos que representam datas e tempos (cf. LocalTime, LocalDate, LocalDateTime), e outras que representam componentes destas datas e tempos (como Year, Month, YearMonth e MonthDay). As classes Period e Duration são duas classes relativamente importantes, pois permitem-nos realizar cálculos relativos a períodos de tempo entre duas datas, dois tempos, etc., medidos nas mais diversas unidades temporais. A classe Period usa valores baseados em datas, contendo ano, mês e dia, enquanto a classe Duration usa nanossegundos como unidades básicas de tais cálculos, sendo por isso mais adequada para a determinação de tempos de máquinas (machine time), tal como a classe Instant. A classe ChronoUnit é uma classe muito versátil e muito útil que determina a quantidade de tempo entre duas datas ou dois tempos nas mais diversas unidades temporais possíveis, isto é, desde anos a nanossegundos. O Tempo Universal Coordenado ou UTC (em inglês, Universal Time Coordinated), também conhecido como “tempo civil”, é o fuso horário de referência a partir do qual se calculam todas as outras zonas horárias (time zone), sendo o sucessor do anteriormente designado Tempo Médio de Greenwich (em inglês, Greenwich Mean Time – GMT). Assim, procurou-se eliminar a referência a um local específico e basear a medida dos tempos em padrões atómicos mais do que em padrões celestes. Os fusos horários têm por referência os meridianos terrestres que estão separados entre si por 15º. Assim, existem no planeta 14 fusos horários distintos, alguns com formas irregulares por razões geográficas, por questões de fronteiras e também por razões políticas. Naturalmente que existem países que, pela sua dimensão, abrangem mais do que um fuso horário. Existem em java.time e em java.time.zone classes que nos permitem trabalhar com as mais diversas zonas horárias (fusos horários ou time zones) e determinar as suas datas e horas locais cf. ZoneId, ZonedDateTime, OffsetDateTime, OffsetTime, ZoneOffset. Quando dois computadores comunicam entre si a partir de pontos geográficos distintos, por exemplo, entre Portugal e o Brasil, estas classes tornam-se muito importantes para que se possam realizar registos de comunicações e transações temporalmente corretos e coerentes, o que, nos dias de hoje, é crucial por várias razões – cf. transações de bolsa, transações bancárias, registos para análise judicial, entre outros. A maioria destas classes de que falámos até aqui representa visões humanas do tempo. Porém, há outras visões do tempo que não são humanas, mas de máquinas que lidam com tempos. A classe Instant representa registos temporais (timestamps) que contam em segundos e nanossegundos o tempo decorrido até à data e tempo atuais, desde o primeiro segundo de 1 de janeiro de 1970, ou seja, desde 1970-01-01 00:00:00. Esta data de referência é também designada por Epoch. Com efeito, todas as modernas linguagens de programação têm Epoch como referência para tempos de máquinas.
266
© FCA – EDITORA DE INFORMÁTICA
O NOVO PACKAGE java.time
9
A antiga classe java.lang.Date estava definida como contando o número de milissegundos decorridos desde o marco temporal Epoch. A nova classe Instant apresenta mais funcionalidade e, tal como outras classes de java.time, passa a registar o número de segundos (long) e o número de nanossegundos desse segundo (int) desde Epoch. Quando trabalhamos com datas e tempos, temos sempre bastantes problemas relativamente ao modo como devemos formatar tais objetos para os apresentar ao utilizador e, inversamente, como ler certas datas e tempos, e realizar a sua validação sintática, isto é, como realizar o respetivo parsing. No package java.time.format teremos a classe DateTimeFormatter e os seus vários métodos, por exemplo, ofPattern(), que nos ajudarão de forma simples nestas tarefas. Teremos ainda métodos que permitem realizar a conversão entre diferentes formatos de datas e tempos. A Tabela 9.1 apresenta de forma sintética as principais funcionalidades de cada um dos packages que constituem a API Date-Time de Java 8. TABELA 9.1 – PACKAGES DA API DATE-TIME DE JAVA 8 Packages de Java 8 para data e tempo
Descrição e funcionalidade
java.time
Representa o núcleo fundamental da API geral para datas e tempos. Inclui 15 classes para manipulação de datas, tempos, datas e tempos combinados, durações, períodos, instantes, clocks e fusos horários. Define dois tipos enumerados para os dias da semana e para os meses. Todas estas classes são baseadas no sistema de calendários definido pela norma ISO-8601. Todos os objetos criados por estas classes são imutáveis.
java.time.zone
Este package contém quatro classes e um tipo enumerado que suportam todas as questões mais complexas da utilização de fusos horários, designadamente regras de alteração da hora de verão ou inverno, etc. As classes de java.time – ZonedDateTime, ZoneId e ZoneOffset – são, em geral, suficientes para qualquer programador. Porém, para cálculos mais rigorosos este package oferece métodos suplementares.
java.time.chrono
Trata-se de uma API genérica que suporta calendários que não satisfazem o formato ISO-8601, permitindo a criação de novos calendários. O package especifica seis interfaces, quatro enumerados e 11 classes. As classes implementam certos calendários muito especiais, tais como o Calendário Budista, cf. a classe ThaiBudistChronology, o Japonês, cf. a classe JapaneseChronology, etc.
java.time.format
API de três classes e quatro tipos enumerados cujo objetivo é fornecer serviços de formatação e parsing para datas e tempos. A classe DateTimeFormatter é a classe fundamental deste package.
java.time.temporal
Esta API torna-se muito importante, dado que oferece funcionalidade para se trabalhar com datas e tempos no que respeita aos seus campos (fields) e a certas unidades de tempo (units), como anos, dias ou minutos. Os nomes dos campos mais comuns estão definidos no enumerado ChronoField. Todas as unidades de tempo implementam a interface TemporalUnit e as mais comuns, como DAYS, MONTHS, YEARS, estão definidas em ChronoUnit. A API oferece ainda serviços para ajustes temporais de datas e tempos, por exemplo, permitindo que nos possamos referir a datas e tempos como “a próxima quarta-feira”, “o primeiro dia do mês”, etc., usando a classe TemporalAdjusters.
Teremos, assim, cinco packages bem caracterizados que, no total, nos oferecem cerca de 40 novas classes, mais de 10 interfaces e mais de 10 tipos enumerados, que nos irão permitir programar de forma muito confortável com todos os conceitos temporais possíveis. Vamos começar por estudar as principais classes do principal package, java.time, onde encontraremos as classes que nos permitirão trabalhar com datas, tempos, datas e tempos, períodos de tempo, durações de tempo, instantes e até fusos horários.
© FCA – EDITORA DE INFORMÁTICA
267
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS
9.2 LocalDate, LocalDateTime E LocalTime Vamos começar por analisar as três primeiras classes de extremo valor do package java.time: LocalDate, LocalDateTime e LocalTime. A classe LocalDate representa uma data sem informação de zona de tempo (time zone) e sem informação de tempo, no formato ISO-8601 – cf. 2016-03-26. A classe LocalTime representa um tempo sem zona de tempo no formato ISO-8601 para horas, minutos e segundos – cf. 13:19:22: –, com precisão até aos nanossegundos, por exemplo, 12:10:20:123456789, e que tem por valor máximo o valor LocalTime.MAX, que corresponde a 23:59:59.999999999. A classe LocalDateTime representa uma data sem informação de zona de tempo (time zone), mas com informação de tempo, no formato ISO-8601 – cf. 2016-03-26 01:01:45. Todas as instâncias destas classes e de todas as outras classes de java.time são objetos imutáveis, isto é, constantes. Qualquer operação sobre um destes objetos temporais dará como resultado uma nova instância da classe sem qualquer modificação do recetor. Associados aos tipos LocalDate e LocalDateTime, encontram-se os tipos correspondentes aos componentes da data, designadamente Month, DayOfWeek, Year e Era. Todas estas classes possuem métodos get adequados aos valores que cada uma representa. Por exemplo, LocalDate terá, entre outros, os métodos int getYear(), Month getMonth(), DayOfWeek getDayOfWeek(), int getDayOfYear() e Era getEra(). A classe LocalDateTime, para além dos métodos anteriores que dão acesso aos campos correspondentes à data, possui métodos que acedem à representação do tempo – cf. int getHour(), int getMinute(), int getSecond() e int getNano(). Os tipos Month e DayOfWeek são tipos enumerados e, para além de uma representação textual, possuem uma representação numérica obtida usando o método getValue(): System.out.println(diaDeAnos.getMonth()); // MARCH System.out.println(diaDeAnos.getMonth().getValue()); // 3
Todas estas classes possuem diversos métodos de classe que permitem criar instâncias de forma direta e simples – cf. os seguintes exemplos usando now(), of() e parse(): LocalDate hoje = LocalDate.now(); LocalDate dataEspecial = LocalDate.of(2016, 3, 21); LocalDateTime agora = LocalDateTime.now(); LocalDateTime limite = LocalDateTime.of(2016, 3, 21, 17, 30); LocalDateTime limite = LocalDateTime.of(2016, 3, 21, 17, 30, 30); LocalTime hora = LocalTime.now(); LocalTime horaRef1 = LocalTime.of(16, 35, 55); LocalTime horaRef2 = LocalTime.of(16, 35, 55, 111111); LocalTime horaNova = LocalTime.parse("12:33");
268
© FCA – EDITORA DE INFORMÁTICA
O NOVO PACKAGE java.time
9
Vejamos alguns exemplos da utilização da classe LocalDate, desde a invocação de métodos de classe para a criação de instâncias (factory methods), até à invocação de alguns dos mais de 50 métodos de instância (de java.time.LocalDate e das outras): // A data de hoje LocalDate hoje = LocalDate.now(); System.out.println(hoje); // 2016-03-05 // Cria data com mês explícito LocalDate seisMar16 = LocalDate.of(2016, Month.MARCH, 6); System.out.println(seisMar16); // 2016-03-06 // Dia de anos; Mostra que março = 3 LocalDate diaDeAnos = LocalDate.of(2016, 3, 21); System.out.println(diaDeAnos); // 2016-03-21 // Calcula a data do 32.º dia do ano de 2016 LocalDate trintaEdoisDiasDe16 = LocalDate.ofYearDay(2016, 32); System.out.println(trintaEdoisDiasDe16); // 2016-02-01 // Em que dia da semana vou fazer anos este ano? System.out.println(diaDeAnos.getDayOfWeek()); // MONDAY // Em que dia do ano vou fazer anos este ano? System.out.println(diaDeAnos.getDayOfYear()); // 81 // Quantos dias tem este ano? System.out.println(diaDeAnos.lengthOfYear()); // 366 // Um mês e quinze dias depois de fazer anos, que dia será? System.out.println(diaDeAnos.plusDays(15).plusMonths(1)); // 2016-05-05 // E 10 anos depois deste? System.out.println(diaDeAnos.plusDays(15).plusMonths(1).plusYears(10)); // 2026-05-05 // Qual o dia da semana que corresponderá ao meu aniversário nos próximos três anos? for(int i = 1; i <= 3; i++) System.out.println(diaDeAnos.plusYears(i).getDayOfWeek()); // TUESDAY // WEDNESDAY // THURSDAY
Como podemos verificar pelos exemplos apresentados, existem métodos para somar ou subtrair dias, meses e anos, para calcular os dias do ano, para determinar o dia da semana, o mês, etc., pelo que temos uma funcionalidade extensa para conhecer e usar.
© FCA – EDITORA DE INFORMÁTICA
269
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS Vejamos alguns exemplos mais concretos de compreensão simples: // Tenho uma multa para pagar. Recebi a notificação a 2016-04-01 // e tenho 35 dias para pagar. Qual é a data-limite? LocalDate dataNotific = LocalDate.of(2016,4,1); System.out.println("Notificação: " + dataNotific); // Notificação: 2016-04-01 LocalDate dataLimite = dataNotific.plusDays(35); System.out.println("Data Limite: " + dataLimite); // Data-limite: 2016-05-06 // Depositei hoje no banco uma quantia que rende juros a seis meses mais um dia. // Qual é a data em que tal acontece? LocalDate dataDeposito = LocalDate.now(); System.out.println("Depósito: " + dataDeposito); // Depósito: 2016-03-06 LocalDate dataJuros = dataDeposito.plusMonths(6).plusDays(1); System.out.println("Data Juros: " + dataJuros); // Data juros: 2016-09-07 // O seguro do meu carro termina a 2016-07-12. Quantos meses faltam? LocalDate dataFimSeg = LocalDate.of(2016,7,12); LocalDate dataHoje = LocalDate.now(); System.out.println(dataHoje); // 2016-03-06 System.out.println("Meses até fim do seguro: " + dataHoje.until(dataFimSeg).getMonths()); // Meses até ao fim do seguro: 4
Este último exemplo possui algo “escondido”, que temos que explicar. O método until() dá como resultado um objeto do tipo Period, que é um triplo com anos, meses e dias. O método getMonths() determina o número de meses desse período e é um método da classe Period e não da classe LocalDate. O exemplo visa mostrar como todas as classes do package java.time são colaborantes e compatíveis entre si, alargando assim a funcionalidade global da biblioteca: // Se hoje é hoje, será que ontem é anterior a hoje? LocalDate dataHoje = LocalDate.now(); System.out.println(dataHoje); // 2016-03-06 LocalDate ontem = dataHoje.minusDays(1); System.out.println(ontem); System.out.println(dataHoje.isAfter(ontem)); // 2016-03-06 // 2016-03-05 // true
Neste exemplo, mostra-se que existem métodos para determinar se uma data é anterior, igual ou posterior a outra – cf. os métodos isAfter(LocalDate ld), isBefore(LocalDate ld) e isEqual(LocalDate ld).
270
© FCA – EDITORA DE INFORMÁTICA
10 CONSTRUÇÕES FUNCIONAIS DE JAVA TÓPICOS ■■
■■ ■■ ■■
Porquê introduzir construções funcionais em JAVA? Encapsulamento de comportamento; Expressões lambda; Interfaces funcionais;
■■ ■■ ■■ ■■
Default methods; Composição de funções; Currying; Closures.
10.1 ENQUADRAMENTO: QUAL O PROBLEMA? Antes de começarmos a apresentação conceptual e técnica de todas as novas construções funcionais de Java 8, é fundamental apresentar as verdadeiras razões que conduziram a estas inovações em Java 8, em especial as razões que levaram a incorporar construções da programação funcional na linguagem JAVA, que é uma linguagem não pura de POO. JAVA foi concebida nos anos 1990 como uma linguagem de POO numa era de grande afirmação deste paradigma, depois da considerável inovação introduzida por Smalltalk. Muitos anos antes de JAVA, existiam inúmeras linguagens de programação funcional, tais como Lisp, Scheme, ML, Miranda, Haskell, entre outras, que eram (e ainda são), em geral, pouco apreciadas, não sendo usadas em ambientes não académicos, mas cujo modelo computacional, baseado nas noções bem conhecidas e bem estudadas de função matemática, expressões condicionais, recursividade, composição funcional, avaliação a pedido (lazy), fontes de dados infinitas, etc., sempre apresentou características matemática e teoricamente muito interessantes. O “cálculo com lambda” (lambda calculus) pode ser considerado a primeira “linguagem” de programação funcional, embora nunca tenha sido projetada para ser realmente executada num computador. Trata-se de um modelo matemático de computação desenvolvido por Alonzo Church por volta de 1930, mas que é ainda muito estudado, oferecendo um modo muito formal de descrever cálculos com funções sem nome, ditas anónimas ou lambdas.
© FCA – EDITORA DE INFORMÁTICA
299
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS Vejamos, apenas por curiosidade, alguns exemplos de expressões lambda do lambda calculus de Church: λx. x + 2 // definição da função que incrementa o seu parâmetro de 2 unidades (λx. 2 * x + 1).3 // aplicação da função definida ao valor 3; resultado = 7 F = λx. x + 2 // função F assume a defnição da função anónima Numa linguagem funcional, as funções são entidades ditas de 1.ª classe, pois podem ser tratadas e usadas como qualquer valor. Assim, as funções podem ser parâmetros de entrada de outras funções, o resultado de outra função e compostas umas com as outras numa sequência computacional. Nas linguagens atuais, as funções podem ser anónimas (cf. as expressões lambda do lambda calculus) ou ter um nome atribuído. Nas linguagens funcionais, as funções são puras no sentido em que produzem resultados exclusivamente a partir dos seus parâmetros de entrada sem modificarem quaisquer dados externos, ou seja, diz-se que não produzem side effects (efeitos colaterais, no vocabulário mais atual). As funções são, portanto, entidades verdadeiramente determinísticas. Não dependem de contextos e para os mesmos dados produzem sempre os mesmos resultados, o que é muito bom para a programação. Por outro lado, como sabemos das matemáticas que estudámos, se uma função tem propriedades associativas, tal como a soma, em que (a + b) + c = a + (b + c) , existem diferentes formas de se encontrar o seu resultado final, ou seja, de realizar a sua computação, usando eventualmente paralelismo. Com o advento das máquinas multi-core, da premente necessidade de se tratar com eficácia volumes cada vez mais massivos de dados e de aplicações de tipo event-driven programming (sistemas reativos) – cf. a maioria dos atuais dispositivos de telecomunicações com interfaces gráficas com o utilizador, os robôs, entre muitos outros –, as linguagens funcionais ganharam uma importância acrescida, devido a algumas das suas características apresentadas anteriormente. Adicionalmente, as linguagens funcionais, sendo de muito alto nível, sempre foram declarativas, ou seja, o que se escreve e lê nos programas é o que se pretende que seja realizado, enquanto no paradigma imperativo expressamos, passo a passo, instrução a instrução, o modo como deve ser realizado, isto é, codificamos o próprio algoritmo.
10.2 ENCAPSULAMENTO DE COMPORTAMENTO JAVA é, de facto, uma linguagem de POO e, como tal, sempre lidou naturalmente com o conceito de encapsulamento de dados, quer se implemente ou não. Na verdade, um objeto pode ser uma impenetrável cápsula de dados protegidos e, adicionalmente, encapsula comportamento. Assim, um objeto é simultaneamente um encapsulamento de dados e um encapsulamento de comportamento. Encapsular comportamento é um mecanismo muito importante, dado que, quando encapsulamos devidamente comportamento, poderemos reutilizá-lo em diferentes contextos. Na história das linguagens de programação, isso foi feito de diversas formas, todas elas úteis.
300
© FCA – EDITORA DE INFORMÁTICA
CONSTRUÇÕES FUNCIONAIS DE JAVA
10
As linguagens de POO fazem-no usando simplesmente objetos (instâncias de uma classe que possuem métodos invocáveis) e as linguagens funcionais fazem-no usando funções. Estas entidades são passadas como parâmetros para determinados contextos e são aí executadas. O problema está, portanto, resolvido em ambas, ainda que de formas diferentes. Porém, ao contrário das funções em linguagens funcionais, em JAVA, os objetos tendem a ser relativamente “pesados” (heavyweighted), porque contêm muitos campos e muitos métodos geralmente desnecessários. Alguma experiência de programação em JAVA leva-nos facilmente a concluir que, em geral, quando pretendemos encapsular comportamento e passá-lo como parâmetro, trata-se de passar como parâmetro objetos que apenas implementam um simples método e não possuem estado interno (atributos). Se pensarmos que um método pode até ser uma função, porque trabalha apenas com os seus parâmetros de entrada e pode devolver ou não um resultado, ao passarmos todo o objeto, para que servem os outros métodos e os atributos? Enfim, para nada. São um “peso” desnecessário para a execução. Se nos lembrarmos de interfaces como Comparator, Comparable, Runnable, ActionListener e muitas outras, que especificam um único método a ser implementado (designadas por SAM types), e como as usámos nos nossos projetos, verificámos que, de facto, apenas precisaríamos de passar como parâmetro um método. Porém, como tal não é possível, todo o processo é de Java 5 a Java 7, demasiado complexo, senão vejamos. Em primeiro lugar, somos obrigados a criar uma interface que define um método; em seguida, criamos uma classe que implementa essa interface; e, finalmente, passamos para o contexto que precisa de tal método uma instância da classe criada. Consideremos um exemplo clássico. Muitos construtores declaram aceitar como parâmetro qualquer implementação de uma interface parâmetro por ele definida. Por exemplo, o construtor de treesets – cf. TreeSet<E>(Comparator<? extends E>); – espera receber como parâmetro uma implementação da interface Comparator<? extends E>, que está predefinida como: public interface Comparator<T> { int compare(T o1, T o2); }
Assim, temos que criar, em primeiro lugar, uma classe com um dado nome, e que por isso é registada na hierarquia de classes sem necessidade implementando apenas o método compare() – cf. o seguinte código: public EmpregadoComparator implements Comparator<Empregado> { public int compare(Empregado e1, Empregado e2) { return e1.getNome().compareTo(e2.getNome()); } }
Depois, passamos como parâmetro uma instância da classe para o construtor TreeSet<Empregado> emps = new TreeSet<>(new EmpregadoComparator());
e, assim, introduzimos uma ordem para os elementos que vão ser inseridos (add ou addAll) no TreeSet<>.
© FCA – EDITORA DE INFORMÁTICA
301
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS Outra solução, não muito conhecida, consiste em usar uma classe anónima interna (anonymous inner class), que é definida anonimamente, não sendo por isso registada na hierarquia de classes, e que é de imediato instanciada, usando new, no contexto em que é definida. Vejamos como: TreeSet<Empregado> emps = new TreeSet<>( new Comparator<Empregado>() { @Override public int compare(Empregado e1, Empregado e2) { return e1.getNome().compareTo(e2.getNome()); } } );
O texto a negrito representa a definição de Comparator<Empregado>, de acordo com a definição do método compare() e a criação da instância usando new, ou seja, definimos uma classe anónima que implementa a interface Comparator<Empregado> e criámos uma instância dessa classe que é fornecida como parâmetro ao construtor de TreeSet<>. Este tipo de construção que permite encapsular e passar comportamento como parâmetro – classe anónima interna – é muito usado sem que, por vezes, os programadores compreendam exatamente o que estão a programar em muito código de JAVA associado a interfaces gráficas com o utilizador (cf. Swing) e em muitas aplicações com concorrência e/ou paralelismo. Eis um exemplo típico de Swing usando a interface ActionListener, definida como: public interface ActionListener { void actionPerformed(ActionEvent e) }
Nestes casos, em vez de se criar uma classe com um nome que implemente a interface, dado que teríamos que ter uma destas classes para cada possível evento, é usual escrever-se código que defina tal classe inline e a instancie de imediato – cf. o seguinte código: button.addActionListener( new ActionListener() { // classe anónima interna public void actionPerformed(ActionEvent e) System.out.println(e.toString()); } );
Ou ainda, usando Runnable: Runnable r1 = new Runnable() { public void run() { System.out.println("Running!"); } }; r1.run();
Este padrão de codificação através de classes anónimas internas é muito usado em diversas bibliotecas atuais de JAVA, em especial nas que lidam com paralelismo, em que o código a executar deve ser independente da thread que de facto o executará. Também nas bibliotecas de JAVA especializadas em lidar com programação reativa (cf. Swing e outras), designadas por bibliotecas de callback, ou seja do tipo evento-resposta, sendo igualmente muito usado na implementação das coleções de JCF. 302
© FCA – EDITORA DE INFORMÁTICA
CONSTRUÇÕES FUNCIONAIS DE JAVA
10
Porém, se o objetivo for criar construções que permitam uma melhor implementação de encapsulamento de comportamento, estas construções apresentam inúmeras desvantagens e imperfeições. Entre outras questões mais técnicas (compilador), a sintaxe é muito confusa (por isso, tivemos que escrever o código a negrito e muito indentado) e existem problemas com a semântica das variáveis, em especial com a pseudovariável this, e várias outras questões muito técnicas relacionadas com o seu funcionamento. Para o programador comum, a questão mais preocupante é a complexidade sintática desnecessária e a complexidade conceptual de ter de programar construções relativamente complexas para algo que, de facto, poderia ser muito simples, designadamente, poder passar um método como parâmetro. Mas tal não é possível em JAVA. Mesmo que fosse possível passar um método como parâmetro, não resolveria o problema de passar código como parâmetro, dado que os métodos são "resolvidos" em tempo de invocação, ou seja, os seus parâmetros são calculados nesse momento. Porém, quando passamos comportamento como parâmetro, o que se pretende é que a sua efetiva avaliação (e dos seus parâmetros) seja realizada apenas quando o contexto para o qual o passamos necessitar de o invocar. Logo, com os métodos de JAVA é impossível. Contudo, com funções e na programação funcional é exatamente isso que se passa: a função é passada como sendo um dado e invocada apenas quando for necessária, e apenas nesse momento são avaliados os valores dos seus parâmetros. Note-se que, caso tal fosse possível, o construtor de TreeSet<> apenas necessitaria de receber como parâmetro um método, ou seja, considerando, por exemplo, a existência de dois empregados, esse método ficaria a comparação dos seus nomes: int comparaEmp(Empregado e1, Empregado e2) { return e1.getNome().compareTo(e2.getNome()); }
O resultado seria o seguinte código final, que não funciona: TreeSet<Empregado> emps = new TreeSet<Empregado>(comparaEmp(e1, e2));
Como sabemos, nada disto é possível em Java 7. Mas, como veremos, tudo passa a ser possível em Java 8, especialmente usando expressões lambda, que são funções anónimas, e também funções com nome próprio.
10.3 MÉTODOS VS. FUNÇÕES A maior diferença entre o uso de métodos e o uso de funções pode e deve ser, desde já, completamente esclarecida: trata-se do momento em que é realizada a avaliação dos respetivos parâmetros (parameter evaluation time). Em JAVA, é possível escrever métodos que recebem parâmetros, apenas trabalham com estes, ou seja, não usam outros valores externos, e devolvem um resultado. Aparentemente, um método parece ser um função. Porém, em JAVA, um método pertence sempre a uma classe e não pode ser usado isoladamente, pelo que jamais poderia ser uma função. © FCA – EDITORA DE INFORMÁTICA
303
JAVA 8 – POO + CONSTRUÇÕES FUNCIONAIS Um método não pode ser usado de uma forma que não seja realizar a sua invocação, o que implica que os seus argumentos sejam de imediato calculados para que o método possa ser executado. Em JAVA, os argumentos são passados por valor e esta é a principal razão da necessidade do cálculo imediato dos seus valores. Os métodos não podem ser passados como parâmetro de qualquer construção, porque não serviriam para nada, pois os argumentos são calculados antes da sua invocação. São, portanto, “constantes de comportamento”, sem qualquer flexibilidade computacional. O que se pretenderia é que a avaliação fosse feita apenas quando o método fosse, de facto, invocado no contexto para onde foi passado. Com métodos de JAVA, isso é impossível. Com funções, essa situação é natural, uma vez que as funções funcionam como code-as-data (mesmo em linguagens não funcionais, como C), ou seja, são passadas como parâmetro como qualquer dado, sem avaliação, sendo apenas avaliadas quando invocadas no contexto para onde foram passadas. O resultado final da sua invocação pode ser, eventualmente, uma outra função, um objeto ou um valor de tipo simples. Comparativamente, os métodos não podem ser passados como parâmetro e nenhum método de JAVA pode devolver um método como resultado. As funções podem ser manipuladas de várias formas sem serem avaliadas, ou até sendo apenas parcialmente avaliadas, e continuando a ser funções. A sua flexibilidade computacional é crucial, daí a importância da sua incorporação em JAVA. Todas as questões relacionadas com a implementação de mecanismos mais funcionais de criação de abstrações de comportamento em JAVA foram estudados no Projeto Lambda (JSR 335) por Brian Goetz. Assim, em conclusão, o grande objetivo do Projeto Lambda foi (e ainda é) introduzir em JAVA expressões de comportamento muito mais concisas e com regras de scope muito mais precisas (ainda que nem sempre funcionais puras – cf. a expressão informal closures por vezes usada, sendo que veremos porquê na secção 10.5.14), remetendo para segundo plano certas construções tradicionais de JAVA, como as inner classes, que, apesar de continuarem a poder ser usadas, se tornarão obsoletas no novo código dos programadores, pois podem ser susbstituídas por construções funcionais, mais claras e mais simples. Finalmente, e em boa verdade, linguagens como C#, Scala e Python já há muito tempo que combinam POO com programação funcional e, portanto, têm bem implementado o encapsulamento de dados e o encapsulamento de comportamento, usando, em geral, construções funcionais e, em especial, lambdas. Scala e Python são linguagens executáveis até na JVM. Porém, C# ainda é menos usada do que C++ e Scala tem um índice de utilização de 0,3%. Objective-C é, surpreendentemente, ainda muito usada (cerca de 11%). JAVA e C disputam ainda a fasquia dos 18 a 20%, sendo que JAVA é a grande linguagem da Web e dos grandes servidores empresariais, e C mantém-se e até tem crescido noutras áreas. Por isso, e em termos reais e pragmáticos, o impacto de modificações na linguagem JAVA, tal como as introduzidas no JDK 8, é enorme, já que não é apenas uma linguagem que está em causa, mas uma plataforma inteira que em Java 7 é composta por 4024 classes e 209 bibliotecas e em Java 8 já atingiu as 4240 classes e 217 bibliotecas. 304
© FCA – EDITORA DE INFORMÁTICA