Neste documento Apontamentos sobre a Linguagem Java 5.0 encontram-se notas sobre a linguagem Java 5.0 que foram tiradas durante a preparação para o exame SCJP da Sun.

Espero que a sua divulgação possa ajudar alguém a melhor compreender a linguagem.

Naturalmente que todas as correcções e sugestões de melhoramento são bem-vindas.

Cenário 1

se só existir esta função,

function a()   {       alert("a()");   }

ela pode ser chamada com qualquer número de parâmetros que o resultado é sempre:

  a();
  a('iuy', 455, 54, 54);

uma caixa de dialogo com a string a(), Não dando qualquer erro de invocação.

Cenário 2

Agora se tivermos, só a seguinte função,

function a(id)   {       alert("a(" + id + ")");   }

Quando for chamado o código,
a();
a(‘iuy’, 455, 54, 54);

mostra as seguintes caixas de dialogo:

  • a(undefined)
  • a(iuy)

Não dando qualquer erro de invocação.
Cenário 3

Duas funções com o mesmo nome, mas com parâmetros diferentes

function a(id)
  {
      alert("a(" + id + ")");
  }
  function a()
  {
      alert("a()");
  }

Só a última é que fica disponível para invocação.

Conclusão: qualquer função pode ser chamada com qualquer número de parâmetros que não será lançado nenhum erro. Os parâmetros da função não preenchidos no momento da invocação terão o valor “undefined”.

Como criar uma classe em javascript:

Definir a classe InputText

/* definição dos tipos */
function InputText(id) // constructor da classe
{
this.id = id; // campos da classe
this.text = ‘jkjh’; // campos da classe

}
// definição das operações através da propriedade prototype de cada classe

InputText.prototype.setTextInInput = function () {
var i = document.getElementById(this.id); // o this indica a instância do objecto que está a invocar a operação

if (i)
{
i.value = this.text;
}
}

InputText.prototype.getTextInInput = function () {
var i = document.getElementById(this.id);
if (i)
{
return i.value;
}
}

InputText.prototype.getText = function () {
this.text = this.getTextInInput();
return this.text;
}

InputText.prototype.setText = function (text) {

this.text = text;
alert(‘a:’ + text);
this.setTextInInput();
}

InputText.prototype.clear = function () {
this.text = ”;
this.setTextInInput();
}

Como usar:

var itext = new InputText(‘itext’);

itext.setText(‘SLB’);

O IE6 e se calhar o IE7 pode ter um comportamento estranho quando é feita a inclusão de um ficheiro javascript numa página HTML. Tem tudo a haver com a forma com a tag <script> é fechada. Ela tem de ser sempre fechada com a tag </script>. ex:

Correcto: <script type=”text/javascript” src=”prototype.js” ></script>

Incorrecto mesmo estando certo do ponto de vista de xml, dá erros estranhos do tipo overflow na linha xxx : <script type=”text/javascript” src=”prototype.js” />

Unicode

Antes do aparecimento do Unicode a forma como os caracteres e símbolos das linguagens humanas eram codificados no computador não era realizada da mesma maneira. As linguagens latinas seguiam a regra de um byte por cada carácter cujo valor é atribuído por uma tabela de caracteres pré-definida como a ASCII ou a ISO-8859-1. Nas linguagens orientais devido ao elevado número de caracteres cada é codificado por múltiplos bytes de acordo com um standard. Para além da quantidade de bytes outra diferença impostas pelas linguagens é a sua orientação de escrita: os ocidentais seguem na sua maioria a orientação da esquerda para a direita enquanto outras linguagens impõe a orientação inversas ou mesmo a orientação de cima para baixo.

Estas diferenças dificultam o processamento informático de textos que têm de combinar diversas linguagens . Para solucionar este problema foi desenvolvido o Unicode por forma a definir uma tabela contendo os caracteres de todas as linguagens e algoritmos que permitem misturar pedaços de textos escritos em linguagens diferentes para definir um todo que seja tratável por um computador.

Tabela de caracteres

A tabela de caracteres do Unicode representa caracteres e não as suas representações gráficas (claro que na tabela de caracteres há uma representação gráfica do mesmo de forma a ser mais fácil a sua identificação). A representação gráfica de cada carácter Unicode é da responsabilidade do designer de fontes para computador. Além dos caracteres presentes nos alfabetos das linguagens mundiais como as latinas, as árabes, a cirilica, a grega, a chinesa, a japonesa, a coreana entre outras há outros caracteres provenientes de notações como a matemática, a música, musica bizantina, Braille, etc,.

Cada carácter no Unicode tem o nome de code element e é identificado por um valor numérico a que se dá o nome de codepoint. Também é caracterizado por um nome unívoco, uma abreviação e por várias propriedades, entre elas as mais importantes são:

  • Categoria, isto é, se é número ou uma letra, ou um simbolo,
  • O seu valor numérico se tal for aplicável,
  • Indicação se é uma letra maiúscula, minúscula ou se só é maiúscula no inicio de uma palavra
  • Tipo, isto é, se é um carácter base, um carácter de combinação, um carácter de formato – (por exemplo, indicação de mudança de linha ) ou um carácter de controle (por exemplo, permitem controlar a orientação do texto).

Dada a quantidade de informação associada a cada carácter ser muito grande o consorcium Unicode distribui essa informação em vários ficheiros de texto a que se dá o nome de Unicode Character Database (UCD).

Desde a versão 3 do Unicode, a mais recente é a 5, que cada carácter da tabela Unicode é representado por um conjunto de 32bits. A actual versão define 99089 caracteres pertencentes a alfabetos mundiais e a diversas notações. O intervalo de valores disponíveis para os codepoints é chamado de codespace, estando definido da seguinte forma: [0, D7FF] e [E000, 10FFFFF], existindo por isso 1 114 112 codepoints possíveis de serem atribuídos a code elements.

Numa tentativa de organizar os mais de 99 mil caracteres a especificação Unicode agrupa os caracteres de acordo com a linguagem ou notação a que pertencem, dividindo assim logicamente as secções do codespace. A cada divisão chama-se um Script.

Os actuais scripts do Unicode são (primeiro é apresentado o intervalo de codepoints e depois o nome do script):

0000..007F; Basic Latin
0080..00FF; Latin-1 Supplement
0100..017F; Latin Extended-A
0180..024F; Latin Extended-B
0250..02AF; IPA Extensions
02B0..02FF; Spacing Modifier Letters
0300..036F; Combining Diacritical Marks

0370..03FF; Greek and Coptic
0400..04FF; Cyrillic
0500..052F; Cyrillic Supplement
0530..058F; Armenian
0590..05FF; Hebrew
0600..06FF; Arabic
0700..074F; Syriac
0750..077F; Arabic Supplement
0780..07BF; Thaana
07C0..07FF; NKo
0900..097F; Devanagari
0980..09FF; Bengali
0A00..0A7F; Gurmukhi
0A80..0AFF; Gujarati
0B00..0B7F; Oriya
0B80..0BFF; Tamil
0C00..0C7F; Telugu
0C80..0CFF; Kannada
0D00..0D7F; Malayalam
0D80..0DFF; Sinhala
0E00..0E7F; Thai
0E80..0EFF; Lao
0F00..0FFF; Tibetan
1000..109F; Myanmar
10A0..10FF; Georgian
1100..11FF; Hangul Jamo
1200..137F; Ethiopic
1380..139F; Ethiopic Supplement
13A0..13FF; Cherokee
1400..167F; Unified Canadian Aboriginal Syllabics
1680..169F; Ogham
16A0..16FF; Runic
1700..171F; Tagalog
1720..173F; Hanunoo
1740..175F; Buhid
1760..177F; Tagbanwa
1780..17FF; Khmer
1800..18AF; Mongolian
1900..194F; Limbu
1950..197F; Tai Le
1980..19DF; New Tai Lue
19E0..19FF; Khmer Symbols
1A00..1A1F; Buginese
1B00..1B7F; Balinese
1D00..1D7F; Phonetic Extensions
1D80..1DBF; Phonetic Extensions Supplement
1DC0..1DFF; Combining Diacritical Marks Supplement
1E00..1EFF; Latin Extended Additional
1F00..1FFF; Greek Extended
2000..206F; General Punctuation
2070..209F; Superscripts and Subscripts
20A0..20CF; Currency Symbols
20D0..20FF; Combining Diacritical Marks for Symbols
2100..214F; Letterlike Symbols
2150..218F; Number Forms
2190..21FF; Arrows
2200..22FF; Mathematical Operators
2300..23FF; Miscellaneous Technical
2400..243F; Control Pictures
2440..245F; Optical Character Recognition
2460..24FF; Enclosed Alphanumerics
2500..257F; Box Drawing
2580..259F; Block Elements
25A0..25FF; Geometric Shapes
2600..26FF; Miscellaneous Symbols
2700..27BF; Dingbats
27C0..27EF; Miscellaneous Mathematical Symbols-A
27F0..27FF; Supplemental Arrows-A
2800..28FF; Braille Patterns
2900..297F; Supplemental Arrows-B
2980..29FF; Miscellaneous Mathematical Symbols-B
2A00..2AFF; Supplemental Mathematical Operators
2B00..2BFF; Miscellaneous Symbols and Arrows
2C00..2C5F; Glagolitic
2C60..2C7F; Latin Extended-C
2C80..2CFF; Coptic
2D00..2D2F; Georgian Supplement
2D30..2D7F; Tifinagh
2D80..2DDF; Ethiopic Extended
2E00..2E7F; Supplemental Punctuation
2E80..2EFF; CJK Radicals Supplement
2F00..2FDF; Kangxi Radicals
2FF0..2FFF; Ideographic Description Characters
3000..303F; CJK Symbols and Punctuation
3040..309F; Hiragana
30A0..30FF; Katakana
3100..312F; Bopomofo
3130..318F; Hangul Compatibility Jamo
3190..319F; Kanbun
31A0..31BF; Bopomofo Extended
31C0..31EF; CJK Strokes
31F0..31FF; Katakana Phonetic Extensions
3200..32FF; Enclosed CJK Letters and Months
3300..33FF; CJK Compatibility
3400..4DBF; CJK Unified Ideographs Extension A
4DC0..4DFF; Yijing Hexagram Symbols
4E00..9FFF; CJK Unified Ideographs
A000..A48F; Yi Syllables
A490..A4CF; Yi Radicals
A700..A71F; Modifier Tone Letters
A720..A7FF; Latin Extended-D
A800..A82F; Syloti Nagri
A840..A87F; Phags-pa
AC00..D7AF; Hangul Syllables
D800..DB7F; High Surrogates
DB80..DBFF; High Private Use Surrogates
DC00..DFFF; Low Surrogates
E000..F8FF; Private Use Area
F900..FAFF; CJK Compatibility Ideographs
FB00..FB4F; Alphabetic Presentation Forms
FB50..FDFF; Arabic Presentation Forms-A
FE00..FE0F; Variation Selectors
FE10..FE1F; Vertical Forms
FE20..FE2F; Combining Half Marks
FE30..FE4F; CJK Compatibility Forms
FE50..FE6F; Small Form Variants
FE70..FEFF; Arabic Presentation Forms-B
FF00..FFEF; Halfwidth and Fullwidth Forms
FFF0..FFFF; Specials
10000..1007F; Linear B Syllabary
10080..100FF; Linear B Ideograms
10100..1013F; Aegean Numbers
10140..1018F; Ancient Greek Numbers
10300..1032F; Old Italic
10330..1034F; Gothic
10380..1039F; Ugaritic
103A0..103DF; Old Persian
10400..1044F; Deseret
10450..1047F; Shavian
10480..104AF; Osmanya
10800..1083F; Cypriot Syllabary
10900..1091F; Phoenician
10A00..10A5F; Kharoshthi
12000..123FF; Cuneiform
12400..1247F; Cuneiform Numbers and Punctuation
1D000..1D0FF; Byzantine Musical Symbols
1D100..1D1FF; Musical Symbols
1D200..1D24F; Ancient Greek Musical Notation
1D300..1D35F; Tai Xuan Jing Symbols
1D360..1D37F; Counting Rod Numerals
1D400..1D7FF; Mathematical Alphanumeric Symbols
20000..2A6DF; CJK Unified Ideographs Extension B
2F800..2FA1F; CJK Compatibility Ideographs Supplement
E0000..E007F; Tags
E0100..E01EF; Variation Selectors Supplement
F0000..FFFFF; Supplementary Private Use Area-A
100000..10FFFF; Supplementary Private Use Area-B

Os caracteres cujo code point pode ser codificados por 16 bits (entre 0 e 65536) estão no plano Basic Multilingual Plane (BMP), correspondendo aos scripts da maioria das linguagens humanas.

O Unicode foi desenhado para ser compatível com algumas codificações já existentes como o código ASCII ou o ISO-8859-1, pelo que os primeiros 255 caracteres são idênticos a esses dois códigos, por exemplo a letra A tem o valor 65(dec) no Unicode, no ASCII e no ISO-8859-1.

Para além dos caracteres das linguagens humanas também estão definidos caracteres que permitem ao computador identificar onde começa uma palavra, uma linha ou um paragrafo, são os chamados caracteres de controlo. A seguir identifica-se alguns dos caracteres de controlo mais importantes:

Caracteres para mudança de linha e de paragrafo:

Acronym Name

Unicode

ASCII

O Unicode define dois caracteres para delimitar linhas e parágrafos. O seu uso não é obrigatório uma vez que também estão definidos os caracteres usados pelo código ASCII para separar linhas. Note-se que no mundo Windows a mudança de linha é identificada pelo par CRLF ao passo que no UNIX a mudança de linha é indicada apenas por LF.

Caracteres identificadores de espaço

Code Name

Caracteres que permitem controlar a direcção do texto, isto é, se ele flui da esquerda para a direita ou vice-versa. São usados quando há uma combinação de texto bi-direccional, senão o seu uso não é obrigatório.

Code Name Abbreviation

O carácter do euro € tem o codepoint U+20AC

Composição de caracteres

Uma diferença do Unicode para os códigos ASCII e ISO-8859-1 é que permite a composição dinâmica de caracteres, isto é, um conjunto de caracteres Unicode combinados entre si podem definir um novo carácter que não está presente na tabela de caracteres. Esta funcionalidade é útil para suportar as linguagens asiáticas. Contudo, do ponto de vista de programação a composição de caracteres elimina a regra “um carácter por cada unidade de codificação” que é valida desde os tempos do ASCII. Para programas pensados para serem executados apenas no Ocidente a regra continua a ser válida uma vez que não é necessário a composição de caracteres para estas linguagens.

Para combinar caracteres é necessário ter um carácter “base” e um ou mais caracteres “combinantes”. Os caracteres combinantes são aplicados sempre ao carácter base que se apresente à sua esquerda, por exemplo: A sequência de codepoints <U0041 U0307> resulta no caractere Ä, uma vez que o U0041 é o caracteres base A e U0307 é caracter combinante ¨.

Do exemplo anterior e de uma inspecção à tabela de códigos do Unicode chega-se à conclusão que já existe o carácter Ä com o codepoint 00C4. Tal facto, deve-se como já foi mencionado anteriormente, de o Unicode suportar standards já existentes como o ASCII ou o ISO-8859-1.

Quando um carácter com um codepoint atribuído é igual a um carácter obtidos através de combinação diz-se que ocorreu uma equivalência.

Encoding

Como os computadores só entendem conjuntos de bits que podem ter o tamanho de 8, 16, 32 e mais recentemente em 64 o standard Unicode definiu de uma forma clara como representar cada codepoint da tabela de caracteres nos diversos tamanhos. São as chamadas codificações (encodings). O standard especifica três:

  • UTF-8: transforma um codepoint numa sequência de tamanho variável de bytes (conjunto de 8 bits).
  • UTF-16: transforma um codepoint num ou em dois conjuntos de words (conjunto de 16 bits)
  • UTF-32: transforma um codepoint num único conjunto de 32 bits.

Independente de cada forma de codificação, há a garantia de cada carácter Unicode ser codificado por uma sequência com no máximo 4 conjuntos (bytes).

A sigla UTF significa Unicode Transformation Format.

A seguinte tabela ilustra os valores das três codificações para quatro caracteres dispersos no codespace do Unicode (os valores estão em hexadecimal e o espaço delimita cada conjunto de bits).

.

Carácter

A

Ω

representação indisponível

representação indisponível

Como pode ser observado, em algumas situações os valores de UTF-16 e UTF-8 não são iguais ao valor do codepoint codificado. Tal facto está relacionado com as regras de cada codificação, que são:

Para a codificação UTF-32:

  • os codepoints são codificados directamente em 32 bits sendo bem formado se estiver entre os valores do codespace Unicode: [0, D7FF] ou [E000 e 10FFFF]

Para a codificação UTF-16:

  • os codepoints entre [0000 e FFFF] (hex), com um número menor que 16bits, são representados directamente numa única Word.
  • os codepoints entre 10000(hex) e 10FFFF(hex) são representados através de duas words usando a seguinte regra:
    • O valor binário de um codepoint na forma 000uuuuuxxxxxxxxxxxxxxxx é codificado em duas words: A primeira constituída por 110110wwwwxxxxxx e a segunda por 110111xxxxxxxxxx, onde wwww=uuuuu-1

Para o UTF-8 (<NU> = Não usado):

Codepoint 1º byte 2ºbyte 3ºbyte 4ºbyte

As codificações UTF-16 e UTF-32 tem variantes para acomodar o tipo de processador que codificou o texto, ou seja se ele é Big-Endien (onde o byte mais significativo é colocado primeiro) ou Litle-Endien (onde o byte menos significativo é colocado primeiro). As codificações para estes casos chamam-se UTF-16-LE, UTF-32-LE, UTF-16-BE, UTF-32-BE e seguem as regras de codificações descritas anteriormente para o UTF-16 e UTF-32. A única diferença é a ordem dos bytes obtidos como resultado da codificação. A codificação UTF-8 não tem variante BE ou LE porque os bits de um byte são processados pela mesma ordem em todas as arquitecturas.

As codificações UTF-16 e UTF-32 levantam um problema de interpretação porque não indicam qual a ordem de leitura dos bytes, ao contrario das codificações UTF-16-BE, UTF-16-LE, UTF-32-BE e UTF-32-LE que especificam claramente a sua ordem. Para resolver este problema, o Unicode definiu o carácter Byte Order Mark (BOM) com o codepoint UFEFF que permite identificar a ordem de leitura dos bytes das codificações UTF-16 e UTF-32.

A inclusão do BOM não é obrigatório, o que nesse caso deixa à consideração da aplicação leitora a interpretação da ordem de leitura dos bytes, embora haja a tendência de ser interpretada como big-endien.

O BOM quando usado para identificar a ordem deve surgir antes da informação codificada (deve ser o primeiro carácter) e dependendo da ordem de bytes usada na codificação o seu valor identifica o ardem de codificação, assim, se o seu valor é :

  • U+FEFF identifica que a informação está codificada na ordem litle-endien
  • U+FFFE indica a ordem big-enfien.

As codificações UTF-16BE, UTF-16LE, UTF-32BE e UTF-32LE não necessitam do BOM porque a ordem dos byte é explicitada pelos sufixos BE (Big-endien) e LE (little-endien).

A seguinte tabela demonstra a codificação de um único codepoint nas várias variantes da UTF-16

Codepoint

Codificação

Valor

Um efeito colateral interessante do uso do BOM é que permite implicitamente identificar que a informação seguinte são caracteres Unicode, embora tal detecção não seja fiável uma vez que o standard não obriga o seu uso. Na codificação UTF-8 o BOM é expresso pela sequência <EF BB BF>, não tendo qualquer significado a não ser que é provável que a informação a seguir seja texto Unicode.

Ordenação e pesquisa de caracteres

O critério de ordenação de caracteres não é uniforme entre as diversas linguagens. Cada uma tem as suas particularidades devido à posição a que atribui aos caracteres do seu alfabeto, como ordena os caracteres com acento ou como ordena os caracteres na forma maiúscula ou na forma minúscula.

Collation é o termo dado à forma como duas string são comparadas de forma a determinar qual a menor e a maior.

No Unicode não se podem comparar Strings de caracteres através da comparação directa do valor do codepoint de cada carácter.

Para comparar String Unicode deve-se usar o Algoritmo “Unicode Colaction Algorithm” que através de uma Collation Element Table consegue ordena as strings. O standard Unicode define a Default Unicode Collation Element Table, como sendo a tabela a usar com o algoritmo.

A tabela Collation Element Table também é usada na operação de pesquisa de caracteres.

Visualização de texto e a Bidireccionalidade

Quando é necessário misturar texto de linguagens com diferentes orientações tem de haver uma maneira de identificar onde começa e acaba cada orientação. Para tal, na tabela de caracteres Unicode há caracteres de controlo caracterizadores da orientação e que devem ser usados de acordo com o algoritmo “Bidireccional Algorithm”.

Os caracteres de controlo só tem influência para a operação de visualização do texto e tem um âmbito de acção somente no paragrafo em que estão presentes. Estes caracteres não têm importância para outros aspectos do texto. Cada paragrafo pode ser delimitado por um carácter de controlo que existe no Unicode.

De uma forma simplista o algoritmo da bidirecionalidade obriga a que o texto com uma determinada orientação começe com o carácter de controlo identificador da orientação, que pode ser o RLE para o sentido direita-esquerda ou o LRE o para o sentido esquerda-direita, seguido dos caracteres de texto a ser visualizados terminando com o carácter de controlo de fim de paragrafo ou com o carácter de controlo PDF (Pop Directional Format ) que anula a ultima orientação dada por RLE ou LRE.

Conclusão

O standard Unicode ao contrário do simples código ASCII ou ISO-8859-1 não é só uma simples tabela gigante com todos os caracteres usados pelas linguagens mundiais, também, apresenta algoritmos que permitem do ponto de vista linguístico processar o texto de acordo com a convenção de cada país e idioma. A título ilustrativo, para além dos já mencionados algoritmos de ordenação, visualização há outros que permitem identificar os limites de um carácter, de uma palavra, de uma frase ou mesmo de um paragrafo.

Referências:

O símbolo do euro é sobejamente conhecido mas levanta enormes dores de cabeça quando é necessário transferir a sua representação entre aplicações ou dentro da mesma aplicação quando a representação é guardada num conjuntos de bytes, por exemplo, um ficheiro ou array.

A linguagem JAVA considera todos os caracteres de uma string como pertencendo ao úniverso de codepoints (numa forma simplista um codepoint corresponde a um caracter do código ASCII) da especificação Unicode. No Unicode o símbolo € está atribuído ao codepoint 20AChex que ultrapassa em muito os 255 valores da tabela ASCII ou da tabela que actualmente é mais usada no nosso país o ISO-8859-1. Na prática a tabela ISO-8859-1 corresponde aos primeiros 255 simbolos da Unicode, por isso, se o universo de caracteres usados por uma aplicação corresponder apenas aos símbolos do ISO-8859-1 pode-se representar cada caracter de uma String num único byte. Iste estratagema serve para o os caracteres acentuados, por exemplo, mas não para o símbolo do euro, que não faz parte do alfabeto do ISO-8859-1

Alfabeto do ISO-8859-1

Portanto, quando for necessário gravar uma String contento o símbolo do Euro num conjunto de bytes, deve-se codificar os caracteres usando os métodos oficiais do Unicode: UTF-8, UTF-16, UTF-32 ou recorrendo a alfabetos que contenham os caracteres normal do alfabeto português e o símbolo do euro. Os alfabetos candidatos são: ISO-8859-15 onde o símbolo do euro tem o valor de A4hex (O ISO-8859-15 é uma actualização do ISO-8859-1 onde uns quantos caracteres menos usados foram substituídos por outros que faziam falta como por exemplo o €) ou o CP1252 do windows onde o euro ocupa o lugar de 80hex.

Windows-1252 (CP1252)
x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
0x NUL
0
SOH
1
STX
2
ETX
3
EOT
4
ENQ
5
ACK
6
BEL
7
BS
8
TAB
9
LF
10
VT
11
FF
12
CR
13
SO
14
SI
15
1x DLE
16
DC1
17
DC2
18
DC3
19
DC4
20
NAK
21
SYN
22
ETB
23
CAN
24
EM
25
SUB
26
ESC
27
FS
28
GS
29
RS
30
US
31
2x SP
32
!
33

34
#
35
$
36
%
37
&
38

39
(
40
)
41
*
42
+
43
,
44
-
45
.
46
/
47
3x 0
48
1
49
2
50
3
51
4
52
5
53
6
54
7
55
8
56
9
57
:
58
;
59
<
60
=
61
>
62
?
63
4x @
64
A
65
B
66
C
67
D
68
E
69
F
70
G
71
H
72
I
73
J
74
K
75
L
76
M
77
N
78
O
79
5x P
80
Q
81
R
82
S
83
T
84
U
85
V
86
W
87
X
88
Y
89
Z
90
[
91
\
92
]
93
^
94
_
95
6x `
96
a
97
b
98
c
99
d
100
e
101
f
102
g
103
h
104
i
105
j
106
k
107
l
108
m
109
n
110
o
111
7x p
112
q
113
r
114
s
115
t
116
u
117
v
118
w
119
x
120
y
121
z
122
{
123
|
124
}
125
~
126
DEL
127
Ax NBSP
160
¡
161
¢
162
£
163
¤
164
¥
165
¦
166
§
167
¨
168
©
169
ª
170
«
171
¬
172
SHY
173
®
174
¯
175
Bx °
176
±
177
²
178
³
179
´
180
µ
181

182
·
183
¸
184
¹
185
º
186
»
187
¼
188
½
189
¾
190
¿
191
Cx À
192
Á
193
Â
194
Ã
195
Ä
196
Å
197
Æ
198
Ç
199
È
200
É
201
Ê
202
Ë
203
Ì
204
Í
205
Î
206
Ï
207
Dx Ð
208
Ñ
209
Ò
210
Ó
211
Ô
212
Õ
213
Ö
214
×
215
Ø
216
Ù
217
Ú
218
Û
219
Ü
220
Ý
221
Þ
222
ß
223
Ex à
224
á
225
â
226
ã
227
ä
228
å
229
æ
230
ç
231
è
232
é
233
ê
234
ë
235
ì
236
í
237
î
238
ï
239
Fx ð
240
ñ
241
ò
242
ó
243
ô
244
õ
245
ö
246
÷
247
ø
248
ù
249
ú
250
û
251
ü
252
ý
253
þ
254
ÿ
255

Tabela do CP1252 (ver original)

Resumindo, o valor de char c = ‘€’ terá o valor de 20AChex no alfabeto do Unicode, nenhum valor em ISO-8859-1 (o java nesta codificação representa-o por um ponto de interrogação ?), A4hex no alfabeto ISO-8859-15 e 80hex no alfabeto CP1252 do windows.

No site oficial da Sun para a plataforma Java encontra-se um artigo que detalha o que é a versão da plataforma Java para os dispositivos que não são PCs mas que tenham um processador mais simples e uma quantidade de memória mais pequena , por exemplo, telemóveis, receptores de TV cabo, frigoríficos, etc,.

O slogan de lançamento da linguagem Java era “Write once, run everywhere”, ou seja, um programa em Java poderia correr em qualquer hardware porque existiria uma implementação da maquina virtual para a executar. Acontece que dentro do mundo dos Pcs esta premissa é relativamente fácil de obter, mesmo com a diferença de tipos de processador e sistema operativo, porque o que caracteriza um PC/workstation/Servidor é a existência de uma placa gráfica, monitor, teclado query, rato, memória, BIOS, disco rígido e processador de pelo menos 32 bits. A distribuição Java Standard Edition, está pensada para executar neste ambiente de hardware.

Fora do mundo dos PCs o que está à volta do processador e da memória é definido pelo fabricante do dispositivo, assim como as características do processador e a quantidade de memória: Um modelo de telefone pode ter uma certa quantidade de memória não encontrada noutro modelo, por exemplo e um electrodoméstico “Java” pode não ter um teclado query, mas apenas algumas teclas de controlo.

Estando identificado as dificuldades de caracterizar o hardware dos dispositivos a suportar como é que a SUN as solucionou? Ela categorizou o harware existente nos dispositivos e definiu para cada categoria quais as funcionalidades que a máquina virtual Java teria de suportar e quais as packages standards da linguagem Java a disponibilizar. As categorias básicas são:

Connected Limited Device Configuration (CLDC): pensado para dispositivos com processadores de 16 e 32 bits, com uma ROM minima de 160 KB e com uma RAM mínima de 32KB. A máquina virtual Java tem restrições relativamente à edição standard implementando a especificação 1.4 da linguagem, sem ter entre outras coisas, finalizadores de classes e grupos de threads. Quanto às packages disponíveis elas são versões simplificadas de :

  • java.lang
  • java.lang.ref
  • java.util
  • java.io

e a inclusão da package javax.microedition.io especializada nas particularidades de input/o utput dos dispositivos.
Connected Device Configuration (CDC): pensado para dispositivos mais potentes que os CLDCs, com processadores de 32bits, tendo pelo menos 2.5Mb de ROM e 2Mb de RAM. Acresce às funcionalidade do CLDC a inclusão de versões simplificadas de outras packages standards como:

  • java.lang.reflect
  • java.math
  • java.text
  • java.util.zip
  • java.util.jar
  • java.net

As configurações CLDC, CDC só definem o ambiente mínimo de execução num dispositivo. Com base nas suas características (existência de ecrân gráfico, de tem teclado, etc) estão definidas especificações que acrescentam packages não existentes na versão desktop da plataforma Java mas que estão adaptadas ao ambiente de execução dos dispositivos. A essas especificações dão-se o nome de profiles e estão distribuidos pelas configurações do seguinte modo:

A configuração CLDC tem os profiles:

  • Mobile Information Device Profile (MIDP), version 1.0 e 2.0
  • Information Module Profile (IMO) versão 1.0 e 2.0
  • Digital Set Top Box profile

A configuração CDC tem os profiles:

  • Foundation Profile
  • Personal Basis Profile
  • Personal Profile

De todos estes profiles e configurações o mais comum é o CLDC/MIDP que é disponibilizado pela maior parte dos fabricantes de telemóveis.

O profile MIDP especifica as seguintes packages:

  • javax.microedition.lcdui
  • javax.microedition.lcdui.game
  • javax.microedition.media
  • javax.microedition.media.control
  • javax.microedition.midlet
  • javax.microedition.pki
  • javax.microedition.rms (gravar e ler dados persistentes)

Informação dos outros profiles e configurações encontra-se no artigo acima mencionado.

A questão é como programar uma aplicação para Mobile Edition. A primeira coisa é verificar quais as configurações e profiles suportadas pelo dispositivo. Esta verificação é estranha para o programador da Standard edition que só se tem de preocupar qual a versão da máquina virtual a suportar.

O ciclo de programação é um pouco mais complicado que o ambiente Desktop porque a fase de codificação e compilação é realizada num PC enquanto que a fase de teste/execução do programa é realizada no dispositivo após a sua transferência. Para acelerar a fase de testes/codificação é normalmente disponibilizado em conjunto com o compilador um emulador do dispositivo para que o programa possa ser executado no próprio PC.

Tomando um exemplo concreto vou tentar exemplificar como tornar o clássico “Olá benfica” numa aplicação mobile e executá-lo num telemóvel Nokia E60.

O telemóvel nókia E60 implementa as seguintes especificações Java Mobile Edition:

  • MIDP 2.0
  • CLDC 1.1
  • JSR 120 Wireless Messaging API
  • JSR 135 Mobile Media API
  • JSR 172 Web Services API
  • JSR 177 Security and Trust Services API
  • JSR 179 Location API
  • JSR 180 SIP API
  • JSR 184 Mobile 3D Graphics API
  • JSR 185 JTWI
  • JSR 205 Wireless Messaging API
  • JSR 75 FileConnection and PIM API
  • JSR 82 Bluetooth API
  • Nokia UI API

sendo constituído por um ecran de 356×416 px, um processador ARM 9 220Mhz, uma RAM de 64 mb. É mais potente que o Olivetti PC1!

Quando se pergunta a um programador se ele sabe programar em Java, ele para ser honesto tem de perguntar primeiro qual o ambiente de programação, é para ambiente Desktop? é programação para o Servidor? é programação para um dispositivo móvel? isto porque um programador Java para além de ter de saber a sintaxe da linguagem, definição de uma classe, de uma interface, do ciclo while como acontecia com as linguagens Pascal, C++ por exemplo, tem também de saber como usar as APIs Swing, o modelo das Servlets, o ciclo de vida de uma página JSF entre outras especificações escondidas atrás da palavra Java.

Como é praticamente impossível a um programador saber tudo de cor, convêm ter à mão referências para consulta:

  • Sobre os aspectos de sintaxe e comportamento da própria linguagem JAVA: http://java.sun.com/docs/books/jls/index.html
  • A documentação JavaDoc da Api que acompanha a distribuição da SUN pode ser visualizada em : http://java.sun.com/javase/reference/api.jsp. O download está em http://java.sun.com/javase/downloads/index.jsp#docs
  • A documentação disponibilizada pela SUN tem um inconveniente: Não é pesquisável! A solução para este problema pode passar pelos seguintes sites:
    • http://www.docjar.com/ tem indexado não só o JavaDoc da Api da distribuição da SUN mas também de outras bibliotecas open source. Outra funcionalidade muito interessante do site é que ao mesmo tempo que se está a consultar a documentação de uma classe pode-se visualizar o seu código através do link source. Muito fixe!
  • A definição de novas funcionalidades da linguagem Java e de todas as outras especificações como JSP, servlets é regida por um processo formal mas aberto à participação de terceiros designado pela SUN como Java Community Process . No site http://www.jcp.org/en/jsr/tech
    é possível aceder aos documentos das especificações. A cada especificação é atribuída um código na forma JSR NN (por exemplo, o código JSR 53 é da especificação Servlet 2.3) passando por várias fases até à sua versão final. Não é incomum que uma JSR tenha dois tipos de documentos: um documento descrevendo a API da especificação – útil para quem usa a especificação – e outro descrevendo pormenores de implementação – útil para os implementadores da especificação.

Será que alguém quer partilhar outros link de interesse?

As bibliotecas de logging como a Log4j entre outras tem a capacidade de adicionar à mensagem de debug indicada pelo programador, o nome da classe, método e número da linha onde foi colocada a mensagem de depuração.

Tendo a curiosidade de saber como é que a linguagem Java é usada para obter informação em run-time de onde um método está a ser chamado pesquisei na Net e deparei-me com a função Thread.currentThread().getStackTrace() que devolve um array com a informação da cadeia de invocações de métodos. O índice zero corresponde à última função chamada, neste caso, a própria getStackTrace() (fixe!), o índice 1 ao penúltimo invocado, etc,. Ou seja é a informação presente no printStack de uma Excepção.

O método writeInfo tenta reproduzir simplisticamente a funcionalidade nuclear das bibliotecas de Logging.

public class DebugInfo {           public static class debug {                   	public void writeInfo(String msg)         {              		StackTraceElement[] stack = Thread.currentThread().getStackTrace();              		StackTraceElement el= stack[2];               		System.out.format("ficheiro:%s class:%s método:%s linha:%s ==> %s",                      		el.getFileName(),                      		el.getClassName(),                       		el.getMethodName(),                       		el.getLineNumber(),                      		msg);          	}      	}           	public static void main(String[] args) {                   		debug d = new debug();          		d.writeInfo("benfica");           	}  }

que devolverá,

ficheiro:DebugInfo.java class:tapete.DebugInfo método:main linha:23 ==> benfica

Nota:Esta técnica só funciona em Java 5.0.

Ao ler o livro Efective Java deparei-me com uma característica da linguagem Java que pensava que não existia: os arrays podem ter zero elementos.

É possível fazer,

String[] a = new String[0];
System.out.println("não é null:" + (a==null));
System.out.println("O tamanho é:" + a.length);
 for(String s :a)
 {
        System.out.println(s);
 }

que devolve,

não é null:false
O tamanho é:0 

A recomendação do livro é que quando um método retorna um array, ele deve retornar um array com tamanho zero em vez de devolver NULL. Desta forma evita-se o recurso ao if para testar se o retorno é null ou se há valor, como é o caso da linguagem C++. Como exemplo desta recomendação observe-se a java.lang.List.

List<String> l = new ArrayList<String>();
String[] la = l.toArray(new String[0]);
System.out.println("la.length = " + la.length);

que devolve,

la.length = 0 

O pedaço de código não funcionaria da mesma forma e o array fornecido tivesse inicialmente elementos no array,

String[] laNull = l.toArray(new String[1]);
System.out.println("la.length = " + la.length);
for(String s :laNull)
{
    System.out.println(s);
}

que devolve,

la.length = 0
null