Integração com Java
Como o NeoObjectPascal é interpretado sobre a JVM, você pode incorporar código Java diretamente no seu programa. Isso dá acesso a todo o ecossistema Java — bibliotecas de data, matemática, texto e muito mais — sem sair da sintaxe Pascal.
Sintaxe de um bloco Java
Um bloco Java é uma expressão que produz um valor. A forma geral é:
java:(arg0, arg1) { <código Java que retorna um valor> }- Entre parênteses vão os valores NeoObjectPascal que você quer disponibilizar ao bloco.
- Dentro das chaves
{ }vai código Java. Ele deve terminar com umreturn. - O valor retornado pelo bloco vira o valor da expressão em NeoObjectPascal.
As chaves são do Java
No NeoObjectPascal, { } delimita exclusivamente o corpo de um bloco Java. Não existem comentários de bloco — comentários são apenas // linha única.
Acessando os parâmetros: param0, param1, ...
Dentro do bloco, os argumentos são acessados por posição, com os nomes param0, param1, param2, e assim por diante. Como o Java é tipado, é preciso fazer o cast para o tipo apropriado:
function saudar(nome: String): String
begin
return java:(nome) {
return "Olá, " + ((String)param0).toUpperCase();
};
end;
begin
WriteLn(saudar("ada"));
end.Olá, ADA
O argumento nome foi entregue ao bloco como param0 e convertido para String antes de chamar .toUpperCase().
Acessando argumentos pelo nome
Quando um argumento do bloco Java é um identificador simples — como em java:(nome) —, você pode referenciá-lo dentro do bloco pelo próprio nome, e não apenas como param0. Esse alias nomeado é declarado com o tipo de runtime do argumento, então, para String, Integer, Boolean e Real, o cast deixa de ser necessário.
function saudar(nome: String): String
begin
return java:(nome) {
// 'nome' já é String — sem precisar de (String)param0
return "Olá, " + nome.toUpperCase();
};
end;
begin
WriteLn(saudar("ada")); // Olá, ADA
end.Olá, ADA
Compare com o estilo posicional antigo, ((String)param0).toUpperCase(): o alias nomeado dispensa o cast e deixa o corpo Java mais legível.
param0, param1, ... continuam disponíveis (totalmente compatível com o código existente) e são a forma de acessar argumentos que não são identificadores simples — como java:(a + b), um literal ou uma chamada de função —, pois esses não têm nome.
Palavras reservadas e colisões
Se o nome do argumento coincidir com uma palavra reservada do Java (class, int, ...) ou com uma variável local declarada dentro do bloco, o alias nomeado é ignorado — nesse caso, use param0.
Múltiplos parâmetros
Cada argumento adicional recebe o próximo índice. Aqui a é param0 e b é param1:
function somaDeQuadrados(a: Integer, b: Integer): Integer
begin
return java:(a, b) {
Integer x = (Integer)param0;
Integer y = (Integer)param1;
return x * x + y * y;
};
end;
begin
WriteLn(somaDeQuadrados(3, 4));
end.25
Usando bibliotecas da JVM
O verdadeiro ganho está em chamar classes do Java. Use sempre o nome totalmente qualificado da classe, pois não é possível declarar import:
function raizQuadrada(numero: Integer): Real
begin
return java:(numero) {
Double n = ((Integer)param0).doubleValue();
return Math.sqrt(n);
};
end;
function agora(): String
begin
return java:() {
java.time.LocalDate hoje = java.time.LocalDate.now();
return hoje.toString();
};
end;
begin
WriteLn("Raiz de 144: ", raizQuadrada(144));
WriteLn("Data de hoje: ", agora());
end.Raiz de 144: 12.0 Data de hoje: 2026-07-17
Repare que agora usa java:() sem parâmetros — o bloco Java pode ser autossuficiente.
Uso direto em expressões
Um bloco Java não precisa estar dentro de uma função: ele pode aparecer diretamente em qualquer expressão, inclusive como argumento de WriteLn:
begin
WriteLn("Cálculo direto: ", java:(10, 20) {
Integer a = (Integer)param0;
Integer b = (Integer)param1;
return a + b;
});
end.Cálculo direto: 30
Como as bibliotecas internas usam isso
As bibliotecas internas do NeoObjectPascal são, em grande parte, escritas com blocos Java. Por exemplo, toUpperCase da biblioteca internal.string é literalmente:
function toUpperCase(s): String
begin
return java:(s) {
return ((String)param0).toUpperCase();
};
end;Ou seja, você pode escrever suas próprias bibliotecas seguindo o mesmo padrão.
Considerações
- Cast explícito: os parâmetros chegam como
Object; faça o cast paraInteger,String,Boolean, etc. - Sem
import: use nomes qualificados comojava.time.LocalDate. - Exceções: exceções Java lançadas no bloco são capturadas pelo runtime e podem ser tratadas com
try/catch. - Desempenho: há um pequeno custo de compilação dinâmica na primeira execução de cada bloco.
Combine com o pipe
Funções que embrulham blocos Java entram naturalmente em pipelines |>. Veja Programação funcional.
A seguir, organize seu código em Módulos e uses.