1
  public class Foo<T> {  
    private T value;  
    public Foo(T value){  
        this.value = value;  
    }

    public Foo<T> Is(){
        return this;
    }

    // At this point, I want a T that implements (extends) Comparable  
    // So i can compare the value.
    // How to do it in Java. 
    public  Foo<T extends Comparable> GreaterThanBar(T anotherValue)
    {
        return this;
    }

 }

This is like a builder pattern I want to do, like fluent style. Chain the methods. etc.

I have the above class, I m trying to convert from C# to Java. In C# I can add the method that where T: IComprable, it works.

How do i do this with Java? I m trying to do this on GreaterThanBar method, so that I can comparare the values.

public <T extends Comparable>  Foo<T> GreaterThan(T another)
{
    if(another.compareTo(value) > 0){
        throw new IllegalArgumentException();
    }

    return (Foo<T>) this;
}

is this the correct way of doing it? Eclipse told me to cast it but i d like to know why i need to cast it to that?

and this worked.

is there a better way to do this?

As a C# developer, I really liked how this is easy to do with C#.

1
  • Does this (i.e. your class) extend Validation<T>? Otherwise your cast is wrong, right? Commented Oct 17, 2011 at 4:12

3 Answers 3

2

You should probably declare your class as:

public class Foo<T extends Comparable<T>>

You don't define that T has to be Comparable until you define GreaterThanBar, so essentially you are defining a subclass of T, and so you prompt the need for a conversion. I think. The semantics of waiting until GreaterThanBar to completely define what T must be is a challenge to understand. Do it at the class level.

Update: Another answer states that the T in the method profile is a different T. That makes sense and explains why the cast is required, but if some self-declared language lawyer could confirm that this is the case, that would be helpful.

Update II: The question is raised: "What if I want to extend Collection too?"

OK, I see what is going on here. You want multiple inheritance. Sorry, but that's not going to happen in Java. In Java, a class can have exactly one super-class. C++ lets you do it. You'll need to re-adjust your thinking. What Java does let you do is have a class implement multiple interfaces. You want to do this:

abstract class A implements Comparable<A>, Collection<A> {

}

class G<T extends A>{

}

When you make a concrete subclass of A, you'll be required to provide implementations of all the abstract methods in Comparable and Collection. Any concrete subclass of A (or subclass of a subclass of A, and so on) can be used in G, guaranteeing that G uses a Comparable class with attributes of a Collection.

Sign up to request clarification or add additional context in comments.

4 Comments

I want a generic class, i want it to extend Comparable and possible other interfaces, depending on what i ll pass.
But T (the one defined in the class definition) does not necessarily extend those interfaces, which is why you will need to cast it. If it is guaranteed to extend them, then you should put it in the class definition, as Steve J has mentioned.
but what if, in some other part i want T to extend from Collection?
I think you want multiple inheritances. Check my addition to the original answer.
1

I'm assuming you want to do something like this:

Validation<Integer> validation = new Validation<Integer>(5);
if(validation.greaterThan(3).isEqualTo(5).isOdd().isValid()) {
    //Do something for when value is valid
} else {
    //Do something for when value is invalid
}

If so, here's a starting point:

public class Validation<T>
    private final T value;
    private boolean valid = true;

    public Validation(T value) {
        this.value = value;
    }

    public Validation<T> greaterThan(Comparable<T> another) {
        if(valid) {
            valid = another.compareTo(value) < 0;
        }        
        return this;
    }

    public boolean isValid() {
        return valid;
    }

    //Other validation methods here...
}

3 Comments

I want to do something similar. not quite. but the starting point is the right point. Thanks.
No worries. Sorry, I just noticed a couple of mistakes. I just fixed it up.
lol :) it s OK. I got the point. All i need was the argument you passed to the method and that worked for me. You dont have to bother more. Thanks again.
1

When you do this in C#, the T on the method is actually different from T on the class. These are two different generic arguments, they just happen to have the same name. If you look closer, you will see a compiler warning about it.

It appears that Java compiler is a bit stricter in this area. All you need to do with this is simply name your generic argument differently. Say, T1. Or U. Or even my personal favorite ThisFreakingGenericArgument.

However, seeing how you're embarking on such a journey, I must warn you. Keep in mind that generics in Java are generally less powerful than those in C#. There may turn out some other things you cannot do.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.