Aqui na empresa onde eu trabalho, por uma série de motivos nos utilizamos uma classe Herdada de BigDecimal e não o próprio BigDecimal.
E agora estamos adicionando Scripts em Groovy no projeto só que eu não consigo utilizar a classe MyBigDecimal do mesmo jeito que eu uso a BigDecimal
exemplo no Script:
BigDecimal x = 1.1+0.1; //Isso funciona
MyBigDecimal y = 1.1+0.1;//Isso NÃO funciona
Alguém sabe se existe alguma maneira de eu usar a classe MyBigDecimal dentro de um Script do mesmo jeito que eu utilizaria a classe BigDecimal
Você definiu os construtores adequados para MyBigDecimal? Provavelmente você terá de definir alguns dos 14 ou 15 construtores que BigDecimal tem .
thingol, ja defini todos os contrutores sim. O erro que o Groovy retorna é o seguinte:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '100' with class 'java.lang.Integer' to class 'teste.types.Decimal'
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:340)
groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:1986)
groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2582)
org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:200)
org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:503)
FormulaTipo0.calcularICM(script1204648740937.groovy:6)
...
onde a classe teste.types.Decimal é a classe herdada de BigDecimal e está com todos os construtores
Perguntinha - o que ocorre se você definir um construtor para MyBigDecimal que receba um java.lang.Integer (que foi o carinha que lhe fez explodir a mensagem de erro?)
Ele ja está la.
Eu estou baixando o src do Groovy pra debugar esse
org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType
e ver o que ele faz ra dar o erro.
Assinatura do método que da o erro na classe org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation:
public static Object castToType(Object object, Class type) {
onde nesse caso object é o Integer de valor 100
e o type é um Class do tipo teste.types.Decimal
dentro do método ele executa um monte de if exemplo:
if(type == String.class) {
return object.toString();
} else if (type == Character.class) {
return box(castToChar(object));
e é lógico que não vai entrar em nenhum if já que ele testa somente == e minha classe não vai estar entre esses ifs, então no final do método como não entrou em nenhum if ele da um throw new nessa exception ai.
Então a pergunta é. Não existe um jeito de configurar algum Helper para executar um construtor personalizado? Porque dai eu poderia criar a classe Decimal a partir deste Helper
Isso o que você está querendo provavelmente não vai funcionar. Quando você faz
def a = 10I;
def b = 10L;
def c = 10G;
Usa-se o método DefaultTypeTransformation.castToType(object, type) para transformar o 10I em um Integer, 10L em um Long e 10G em um BigDecimal. Portanto quando você tenta
Decimal d = 10;
// ou
Decimal e = 10 as Decimal;
O mecanismo de conversões do Groovy não consegue encontrar nenhuma condição que satisfaça a transformação de um numérico para seu tipo personalizado e daí vem seu erro.
Contudo, você pode tentar isso:
def f = new Decimal(10);
println(f.class); // com.acme.Decimal
Que vai funcionar tranquilamente, com um porém. Se você fizer alguma operação aritmética com a variável f, o tipo da variável vai mudar de com.acme.Decimal para java.math.BigDecimal, porque os operadores aritméticos foram sobrecarregados para suportar apenas BigDecimal e não seus prováveis sub-tipos.
println(++f); // 11
println(f.class); // java.math.BigDecimal
O que fazer? Você pode criar um wrapper, em Groovy, do seu tipo personalizado e sobreescrever, entre outras coisas, métodos como add, divide, etc… Lembre-se de fazer este seu wrapper estender java.lang.Number. A chance disso funcionar é grande (desculpe, não testei aqui para verificar). Acho que é isso.