Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I define a template class by constraining the set of allowed types, and reference a Collection of these in Java?

Tags:

java

generics

I am defining the following class:

public class Foo<T> {
    T _value;

    public T getValue() { 
        return T;

    public void setValue(T value) {
        _value = value;
    }
}

T should only be of type int, char, or double.

I want to be able to reference a collection of these, such as:

interface IBar {
    Collection<Foo> getAllFoo();
}

Obviously, this doesn't work since I'd need to specify the type T with this reference. So, I need to define some abstract base class that I can use instead.

The question is, how can I enforce that all derived types implement the getValue() and setValue() functions? I know I can define them in the abstract base as abstract methods returning / accepting an Object, but that doesn't provide type safety on the 3 accepted primitives.

Is there a better way to define a collection of these, and is there a way to enforce T being either int, char, or double?

like image 955
retrodrone Avatar asked Jan 28 '26 16:01

retrodrone


1 Answers

You're better off creating concrete implementations for each type you care about.

interface Foo<T>{
    public T getValue();
    public void setValue(T value);
}

class IntFoo implements Foo<Integer>{...}
class CharFoo implements Foo<Character>{...}
class DoubleFoo implements Foo<Double>{...}

interface Bar{
    Collection<Foo<?>> getAllFoo();
}

The ? allows the collection to contain any type of Foo object. You still lose the generic type when you reference a Foo<?>, but there's no good way around that.

Other than having the common base class, there really is no advantage of doing this. If you had some common ground each Foo could resolve to, then I would do this:

abstract class Foo<T>{
    T value;

    T getValue(){
        return value;
    }

    void setValue(T value){
        this.value=value;
    }

    // return whatever is appropriate for all implementations
    abstract Object baz(); 
}

class IntFoo implements Foo<Integer>{
    Object baz(){
        return null // something useful;
    }
}

Collection<Foo<?>> foos = bar.getAllFoo();
for(Foo<?> foo:foos){
    foo.baz();
}
like image 200
Jeremy Avatar answered Jan 30 '26 06:01

Jeremy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!