Converting from Java to Groovy. Problems with dynamic type promotion. How do I disable it?

Asked

Viewed 135 times

-1

I’m converting an old Java application to Groovy. The syntax conversion is smooth. The problem is dynamic Groovy typification.

Let me give you an example, I declare a method foo and its overload:

int foo(String arg) {
    return 1;
}

int foo(Object arg) {
    return 2;
}

Then I apply the method foo on an instance of the type Object what reference a type String:

Object obj = "PT Stack Overflow";
int resultado = foo(obj);

Applying the method in Java System.out.println() or the method in Groovy println() get different results for each language:

In Java:

System.out.println("Em Java o resultado é " + resultado );
> Em Java o resultado é 2

In Groovy:

println("Em Groovy o resultado é " + resultado );
> Em Groovy o resultado é 1

This is because the Java and Groovy overloaded methods dispatch system are distinct. Java chooses the method according to the signature of the parameters and Groovy uses a type self-promotion system.

I would like to know how I do to disable this dynamic typing system when invoking methods because in my application I have portions of code where there are overloaded methods that perform the same task, however, based on the guy of the parameter passed the program opens distinct subforms and the Groovy conversion is practically useless.

  • You can’t specialize anymore int foo(Object arg), with an interface, for example?

  • How would using an interface modify dynamic type checking? From what I know an interface only stipulates a minimum set of methods to be implemented by a class.

  • 1

    Who negatively could comment and help improve my question?

1 answer

4


Groovy is a dynamic language and by default uses a dynamic dispatch mechanism to execute method calls and properties accesses.

This dynamic dispatch system provides great flexibility and power to language. For example, it is possible to dynamically add methods to classes at runtime as well as replace methods at runtime. Features like this are important and provide a lot of power to language.

In any case, there are times when you want to disable this dynamic dispatch in favor of a more static mechanism. For this Groovy provides a means to inform the compiler that a particular class or a specific method must be compiled statically. This means to mark the class, or method, with the comment groovy.transform.Compilestatic.

groovy.transform.CompileStatic allows the Groovy compiler to use Java-style type checking thus performing a static build overriding the Groovy protocol for meta objects.

When a class is marked with groovy.transform.CompileStatic all methods, properties, nested classes and etc. of the marked class will inherit this type check. When a method is marked the static compilation only applies to its items(closures and nested anonymous classes).

So to make a Groovy method behave like a Java method just mark it with groovy.transform.CompileStatic as in the example:

class Bars{

  // A anotação seguinte só se aplica em Groovy
  @groovy.transform.CompileStatic
  int foo(String arg) {
      return 1;
  }

  // A anotação seguinte só se aplica em Groovy
  @groovy.transform.CompileStatic
  int foo(Object arg) {
      return 2;
  }
}

Bars B1 = new Bars();
Object obj = "PT Stack Overflow";
int resultado = B1.foo(obj);

System.out.println("Em Java o resultado é " + resultado );
> Em Java o resultado é 2

println("Em Groovy agora o resultado é " + resultado );
> Em Groovy agora o resultado é 2

Browser other questions tagged

You are not signed in. Login or sign up in order to post.