es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El tipo genérico no puede ser inferido.

Dado el siguiente archivo de construcción:

class Factory {
    public static <T> FooBuilder<T> fooBuilder() {
        return new FooBuilder<>();
    }
}

class FooBuilder<T> {
    int x;

    public FooBuilder<T> addFooStep(int x) {
        this.x = x;
        return this;
    }

    public Metric<T> build() {
        return new Metric<>(x);
    }
}

class Metric<T> {
    final int cm;

    public Metric(int cm) {
        this.cm = cm;
    }
}

En algún lugar se pierde la información del tipo T. Por lo tanto, para usar este constructor, tengo que especificar explícitamente el tipo como:

Metric<Integer> integerMetric = Factory.<Integer>fooBuilder()
                .addFooStep(1)
                .build();

Sin embargo, me gustaría poder usarlo sin la notación explícita de tipo, como:

Metric<Integer> integerMetric = Factory.fooBuilder()
                .addFooStep(1)
                .build();

¿Es esto posible y, de ser así, cómo se puede lograr?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible utilizar el generador sin especificar explícitamente el tipo mediante el uso de la inferencia de tipos. Para lograr esto, el método fooBuilder() necesita actualizarse para utilizar la inferencia de tipos reemplazando la firma del método public static <t> FooBuilder<t> fooBuilder() con public static FooBuilder<?> fooBuilder(). Esto permite al compilador inferir el parámetro de tipo del tipo devuelto de la llamada al método.

    Por lo tanto, el código actualizado sería:

    class Factory {
        public static FooBuilder<?> fooBuilder() {
            return new FooBuilder<>();
        }
    }
    
    class FooBuilder<t> {
    
        int x;
    
        public FooBuilder<t> addFooStep(int x) {
            this.x = x;
            return this;
        }
    
        public Metric<t> build() {
            return new Metric<>(x);
        }
    }
    
    class Metric<t> {
    
        final int cm;
    
        public Metric(int cm) {
            this.cm = cm;
        }
    }
    

    Y ahora el siguiente código funcionaría como se desea:

    java
    Metric<integer> integerMetric = Factory.fooBuilder()
    .addFooStep(1)
    .build();

Comments are closed.