Generic argument - java

I would like to create an Java interface with a method that accepts all subtypes of a type:
interface A{};
interface B{
void method(A a);
}
What I want to accomplish is to make an implementation of the method(A a) accept
all subtypes of A (like return type polymorphism but with an argument).
Is this even possible?

You've already done it!
To prove it, try something like this:
public class ThisA implements A {}
public class ThatA implements A {}
public class OtherA implements A {}
public class SubclassA extends OtherA {}
then call your method:
B b = new B {
public void method(A a) {
System.out.println("Called with "+a);
}
}
b.method(new ThisA());
b.method(new ThatA());
b.method(new OtherA());
b.method(new SubclassA());

Related

Java generic parameter as exact subclass?

Assuming we have a method like this:
public void foo(Class<? extends ClassBar> x) {
...
}
By modifying the generic expression;
< ? extends ClassBar >
Is it possible to ensure that ClassBar.class can't be passed in but anything extends ClassBar directly or indirectly be passed in WITHOUT throwing an exception on the runtime?
If you have only a bunch of classes extending ClassBar you can follow these two approaches.
Solution 1:
have all subclasses of ClassBar extend a custom interface (except for ClassBar itself), and change the method signature to:
public <T extends ClassBar & MyInterface> void foo(Class<T> x) {
...
}
Solution 2:
use something similar to this #AndyTurner's trick and provide instances only for specific types.
E.g:
class ClassBar {}
class ClassBarA extends ClassBar{}
class ClassBarB extends ClassBar{}
Your class containing foo:
class Foo<T extends ClassBar> {
private Foo() {} // private constructor
public static <T extends ClassBarA> Foo<T> instance(T c) {
return new Foo<T>();
}
public static <T extends ClassBarB> Foo<T> instance(T c) {
return new Foo<T>();
}
public void foo(Class<T> c) {
}
}
Only subclass of ClassBarA would be accepted in this case
Foo<ClassBarA> foo1 = Foo.instance(this.classBarA);
foo1.foo(ClassBarA.class); // pass
foo1.foo(ClassBar.class); // fail

Java Generics - Compile time validation of type and implementing object

I have a method to add implementing class' objects against interface class and I want to make this as a generic one.
The implementing class also extends a class X
public abstract class X<T>{...}
public interface InterfaceA{...}
public class A extends X implements InterfaceA{...}
now, currently my method is:
public <S, <T extends X<S>> void add(Class<S> clazz, T object){...}
But I have no use of type parameter on X, it is just for the above method. Is there a way I could have X without type parameter and still have compile-time validation in method 'add' please?
Thanks
EDIT:
I think my question is not clear. Please look at the below example code:
public interface I {}
public abstract class X {}
public class A extends X implements I {}
public class B implements I {}
public class C extends X {}
public class Main {
public static void main(String[] args) {
add(I.class, new A()); // uses first method
add(I.class, new B()); // uses second method
add(I.class, new C()); // uses first method
}
public static <P, T extends P> void add(Class<P> c, T object) {} //No
public static <P, T extends X> void add(Class<P> c, T object) {} //No
}
I need an 'add' method that just accepts A's instance and not B's not C's.
Both the above method signature don't fulfill my requirement
If you don't care about the type parameter of X, just make it Object:
public class A extends X<Object> implements InterfaceA{...}
So the method will work with anything.
I believe you can remove the type on X and still get a compile-time error for add in the following manner. Now, of course, a little more context will be more helpful if this doesn't meet your requirement.
public abstract class X {
}
public class A<T> extends X implements InterfaceA {
public <S, M extends X> void add(Class<S> clazz, M object){
}
public void abc() {
Class<String> clazz = String.class;
this.add(clazz, new B());//This should throw compilation error
}
}
public class B implements InterfaceA {
}

generic interface that only allows objects that implement other interfaces

I have an interface A, and wish to write an generic interface B such that any T that implements B must also have implemented both A and Comparable. A is not currently a generic interface.
Is this possible? Do I need to make A generic?
I had hoped to be able to write something like:
public interface B<T implements Comparable, A> {}
But this does not seem to work... Can anyone point me in the right direction?
I do not believe this is a duplicate of the question that has been linked.
What you are looking for here are multi-bounded generic types:
public interface B<T extends A & Comparable> {}
Note that if either of the bounded types is a class instead of an interface, it has to be the first bound defined after extends. Also, you cannot use multi-bounded generic types on more than one class(since there is no multiple-inheritance in Java)
Just make B to extend A and Comparable.
public interface A {
public void methodA();
}
public interface B<T> extends A, Comparable<T> {
public T methodB();
}
public class BImpl<T> implements B<T> {
#Override
public T methodB() {
return null;
}
#Override
public void methodA() {
}
#Override
public int compareTo(T o) {
return 0;
}
}

Type check parameter is a (sub)class and also implements an interface

This answer no doubt exists on SO, but I haven't found the right combination of search terms to come up with it.
I have a method that I want to take a parameter that is of class A, but also implements interface B. How do I do it?
e.g.
public class MySubclassWithInterface extends MyClass implements MyInterface { }
public class MySubclass extends MyClass { }
public class MyInterfaceClass implements MyInterface { }
public class MyOtherSubclassWithInterface extends MyClass implements MyInterface { }
Out of the three classes above, I only want my method to accept an object that is MyClass and implements MyInterface, in other words, either MySubclassWithInterface or MyOthersubclassWithInterface but not MySubclass or MyIntefaceClass
I very sheepishly tried the following which obviously failed:
public void myMethod( (MyClass MyInterface) parameterName) {
...
}
Thanks for your help in advance.
You can express this with a generic type as in the following signature:
<T extends MyClass & MyInterface> void m(T p)
The rule is that the first type must be a class or an interface and any following parameter must be an interface type.

Generics in java, extending interfaces

In the code below:
class A<T extends InterfaceA & InterfaceB>
what does it mean "T should be a type of InterfaceA"?
for example the next code:
class A<T extends Number>
means that T can be an int, a double or any other numeric types.
can anyone give me an example to explain the first code?
It says T must be a type that implements both interfaceA and interfaceB interfaces.
Your second example says that T must be of any type that implements the Number interface only.
class A<T extends interfaceA & interfaceB> means
that T is bounded by two interfaces. Thus,any type argument passed to T must implement interfaceA and interfaceB.
Sample program for your understanding :-
interface X{
public void eat();
}
interface Y{
public void drink();
}
class XYZ implements X,Y{
#Override
public void eat(){
System.out.println("I am eating.");
}
#Override
public void drink(){
System.out.println("I am drinkin too!");
}
}
class A<T extends X & Y> {
public void display(){
XYZ x=new XYZ();
x.eat();
x.drink();
System.out.println("Type of XYZ is "+x.getClass().getName());
}
}
public class Sample1{
public static void main(String[] args) {
A<XYZ> a=new A<>();
a.display();
}
}
This means that type which argument passed to T must implement interfaces X and Y.
Like shown in the given code :-
A<XYZ> a=new A<>(); //here only XYZ(substituted in place of T) can be passed because it implements both interface X and interface Y
I hope this much helps you understand and point out the differences!!!
I would go with #shekhar suman's example, but i would change last class and main:
class A<T extends X & Y> {
public void display(T t){
t.eat();
t.drink();
System.out.println("Type of T is "+t.getClass().getName());
}
}
public static void main(String[] args) {
A<XYZ> a=new A<>();
a.display(new XYZ());
}
If there was no extends like this:
Class A<T>
Class A was a generic class, accepting any class T.
However in case of
Class A<T extends InterfaceA & InterfaceB>
T can be any class that implements both interfaceA and interfaceB.
In other words you want to make sure T is not any random class, and satisfies some conditions.

Categories

Resources