Java F-Bound bound by interface - java

Notation: Inter is interface; Abs[N] is an abstract class.
The following code works fine in Java without a problem:
public class Impl<T extends Abs1<T>> extends Abs2<T> {...}
However, if you want to introduce another bound by an interface on T, I haven't found any easy way to do it, namely:
public class Impl<T extends Inter & Abs1<T>> extends Abs2<T> {...}
won't work because Abs1 as an abstract class cannot be used as a bounding parameter. The simplest, but ugly (is it ugly?) solution I have found is:
public class Impl<B extends Inter, T extends Abs1<B>> extends Abs2<T> {...}
I have a hunch that in Scala with the traits there exists a more elegant solution, but are there any tips for Java?

Oh my... well, this is embarrassing. I was so focused on the F-Bound, that I forgot that this comes directly from the JLS, section 4.4:
Every type variable declared as a type parameter has a bound. If no bound is declared for a type variable, Object is assumed. If a bound is declared, it consists of either:
a single type variable T, or
a class or interface type T possibly followed by interface types I1 & ... & In.
In other words the (abstract) class declaration must come first in an intersection type. The described behaviour has nothing to do with F-Boundedness. I.e., the following works:
public class Impl<T extends Abs1<T> & Inter> extends Abs2<T> {...}
This is also described in the Java Tutorial. If one thinks about it, it is self-explanatory, hence this way the parser has an easy way to check for double-inheritance (which is prohibited).

Related

Extending a generic class with and without types gives different implement methods in IntelliJ IDEA?

I was trying to extend the org.apache.flink.api.common.io.FileInputFormat class in Apache Flink that has the following signature
public abstract class FileInputFormat<OT> extends RichInputFormat<OT, FileInputSplit> {}
For completeness, the signature of the RichInputFormat class is,
public abstract class RichInputFormat<OT, T extends InputSplit> implements InputFormat<OT, T> {}
It (the first class - FileInputFormat) has two abstract methods public boolean reachedEnd() and public OT nextRecord(OT reuse)
Now, if I extend with types as,
public class MyInputFormat<T> extends FileInputFormat<T>{}
then IntelliJ, as expected, suggests (Ctrl+I) to implement these two abstract methods, which is correct and needed to compile the program.
However, if I extend without types as,
public class MyInputFormat extends FileInputFormat{}
then IntelliJ suggests implementing two other methods in the InputFormat interface, which are already implemented in the FileInputFormat class. These methods are public InputSplitAssigner getInputSplitAssigner(InputSplit[] inputSplits) and public void open(InputSplit split).
In fact, these are not necessary to compile the program, though one may prefer to override them.
Any logical reasoning for this behavior?
I think that this is a peculiarity of IntelliJ. The two additional methods that are suggested depend on some generic parameter defined in the super interface "InputFormat".
Apparently IntelliJ assumes the to additional methods should be overridden, when the generics types are dropped.
This looks almost like a small bug: When using a raw type in Java, the type parameters should default to their lower bound (here "Object" for "T").
But in this case, also the defined parameters of "FileInputFormat" (namely "FileInputSlit") are dropped.

Keyword extends with Type Parameter<T> in Generic Java

Consider
Gen<T>
So, when I write something like this
Gen<Integer> someRef = new Gen<>();
Gen<String> someRef = new Gen<>();
As per my understanding,
The Java compiler does not actually create different versions of Gen,
or of any other generic class. Although it’s helpful for me to think in these terms,
it is not what actually happens. Instead, the compiler removes all generic
type information, substituting the necessary casts, to make my code behave
as if a specific version of Gen were created.
Thus, there is really only one version of Gen that actually exists in my program.
The process of removing generic type information is called erasure.
Now consider this one,
interface MinMax<T extends Comparable<T>> {
In general, a generic interface is declared in the same way as is a
generic class.
In this case, the type parameter is T, and its upper bound is Comparable, which is an
interface defined by java.lang. A class that implements Comparable defines objects
that can be ordered. Thus, requiring an upper bound of Comparable ensures that MinMax
can be used only with objects that are capable of being compared. Notice that
Comparable is also generic. (It was retrofitted for generics by JDK 5.)
It takes a type parameter that specifies the type of the objects
being compared.
Next, MinMax is implemented by MyClass.
Notice the declaration of MyClass, shown here:
class MyClass<T extends Comparable<T>> implements MinMax<T> {
Here comes my confusion,
When I will write something like this,
MyClass<Integer> ......
Type parameter T will be replaced by Integer. or say any other version(depends on type of Objects I will be operating).
I know very well that a class implements an interface. With regard to aforementioned, wouldn't the above case work like this,
class MyClass<Integer(or some other version) extends Comparable<Integer>> implements MinMax<Integer> {
So, how come a class here is extending an interface,
Integer(or some other version) extends Comparable<Integer>
I know for sure, my understanding is not correct regarding the above context. Kindly elaborate?
The reason is that in Generics the keyword extends is used in a different context.
In Generics, T extends Something denotes that T will be a sub-class of Something or will implement Something (in the cases of an interface). The type of the bound doesn't really matter (class or interface) - what matters is T to be sub-type of the provided bound.
More info:
Why extends interface instead of implements interface?

How can I define a generic class that implements two interfaces?

I don't think this is a duplicate of Check if a generic T implements an interface, but it may be(??).
So, I want to create a generic interface that only allows objects that implements two interfaces. Alike is a costum interface.
public interface AbstractSortedSimpleList<T extends Comparable<T>, Alike> {}
If I understand it correctly, Java now tries to create a generic interface AbstractSortedSimpleList<T,Alike>, which isnt exactly what I want to achieve. I want AbstractSortedSimpleList<T> where T has to implement both Comparable<T> and Alike.
Later, I want to make a new class
public class SortedSimpleList<T> implements AbstractSortedSimpleList<T> {}
The point here is to create a class SortedSimpleList<T> where T has to be implementing the aforementioned interfaces. But my code does not seem to work very well.
You can give multiple bounds to type parameter:
public interface AbstractSortedSimpleList<T extends Comparable<T> & Alike>
Then, your SortedSimpleList would be like:
class SortedSimpleList<T extends Comparable<T> & Alike> implements AbstractSortedSimpleList<T> {}
See JLS §4.4:
Every type variable declared as a type parameter has a bound. If no bound is declared for a type variable, Object is assumed. If a bound is declared, it consists of either:
a single type variable T, or
a class or interface type T possibly followed by interface types I1 & ... & In.
Note:
You can't have such multiple bounds for wildcards though. It's only for type parameters.
References:
Java Generics FAQs - Type Parameter bounds
Use some generic bounds with the & notation
interface AbstractSortedSimpleList<T extends Comparable<T> & Alike> {
See the official Java tutorial on multiple bounds, here.

Self bounded generics

Is there is any actual difference between these this generic
public class SelfBounded <T extends SelfBounded<T>>{}
and this one
public class SelfBounded <T extends SelfBounded>{}
?
If yes, then how can I observe them?
There are a lot of similar questions here already.
You can read the following article
Or the following questions:
Java Enum definition
Why in java enum is declared as Enum<E extends Enum<E>>
What would be different in Java if Enum declaration didn't have the recursive part
The second one uses a raw type, which should never be used.
But actually neither of these declarations are normally useful. You should almost certainly just use
public class SelfBounded <T>

Java - passing ArrayList of interface type

I have an interface Damageable as follows
public interface Damageable {
public void handleCollision(float impulse);
}
a class which implements this interface, BaseObject
public class BaseObject implements Damageable
Now in a third class, I have an ArrayList of the type BaseObject
public class ObjectManager {
public ArrayList<BaseObject> bodies;
What I am trying to do is to pass the ArrayList bodies to a method of another class which accepts ArrayList
public CollisionManager( ArrayList<Damageable> _bodies) {
bodies = _bodies;
}
Java does not let me do new CollisionManager(bodies) where bodies is of type ArrayList and BaseObject implements Damageable
I have tried casting. Says cannot cast from
ArrayList<BaseObject> to ArrayList
Also tried using Class<? extends Damageable> but then I'm unable to call methods declared in the interface Damageable. How can I pass the ArrayList?
You have to be explicit with your generics. Therefore, you have to inform the compiler that your generic type doesn't have to be a Damagable per se, rather it can extend Damagable:
public CollisionManager(ArrayList<? extends Damagable> bodies) {
By the way, notice that I changed your variable to bodies rather than _bodies. Underscores are not part of the standard Java coding conventions.
Edit in response to the OP's comments
Let's say that, instead of an interface, you had a concrete class called Damagable. Telling the compiler <? extends Damagable> says that it doesn't have to be an instance of Damagable. It's okay that the type extend Damagable. Otherwise, the compiler assumes that you have a Damagable exactly.
It doesn't make as much sense when you think of Damagable as an interface, since there is not case where you would have an instance of Damagable. But they work in essentially the same way.
You have to remember that you're working with Java types, not classes. Java's type syntax and structure is less robust than it's class structure. There is no concept of implements when it comes to types.
Last round of edits
Finally, I should note that it's generally better to use an interface for method/constructor parameters and method return types. This allows you and those that use your methods to use whatever implementation you please, and allows you to change your implementation as you please.
So with those revisions, you would have:
public CollisionManager(List<? extends Damagable> bodies) {
Try ArrayList<? extends Damageable > _bodies.
This says that you want an ArrayList consisting of a Class that extends (well implements) Damageable
Others will no doubt point out the technical solutions from the Java syntax perspective.
I'm just going to mention a few design issues that you should perhaps consider:
Your BaseObject implements Damageable. That means all BaseObjects are Damageable. Why not then just make a CollisionManager(ArrayList<BaseObject>)? Unless you are going to use Damageable elsewhere (i.e. there are things which are Damageable but are not BaseObjects) then it seems like an unnecessary abstraction.
Usually for collision detection in a game / simulation you would want to use a spatial data structure for collision detection (e.g. Octree, Quadtree or AABB tree) rather than an ArrayList. Searching for collisions in an ArrayList is an O(n^2) algorithm. This will become a big issue if you have a lot of live objects.
Damageable seems like a bad name, since the functionality relates to collision detection rather than damage - wouldn't Collidable be better?

Categories