I need a way to query different parse classes based on choices made by a user. I approached the problem as follows. Please advise how to fix the problem I have or suggest alternative/better approach.
I have classes A, B, C, ... that correspond to Parse classes. They are very similar. So, I created abstract class Q:
public abstract class Q extends ParseObject {
// some shared methods
public abstract ParseQuery<? extends Q> getQuery();
}
Each of A, B, C, ... is defined as:
#ParseClassName("A")
public class A extends Q {
private static final A INSTANCE = new A();
#Override
public ParseQuery<A> getQuery() {
return ParseQuery.getQuery(A.class);
}
public static A getInstance(){
return INSTANCE;
}
}
Than I have the following recycle adapter for my recycle view:
public class QAdapter extends ParseRecyclerQueryAdapter<Q,QAdapter.MyViewHolder>{ ... }
The error I am getting happens on the following line in my activty:
mRecyclerAdapter = new QAdapter(this, factory, true);
The error message is:
Error:(58, 70) error: incompatible types: QueryFactory<CAP#1> cannot be converted to QueryFactory<Q>
where CAP#1 is a fresh type-variable:
CAP#1 extends Q from capture of ? extends Q
I tried to make the definition of adapter class generic as public class QAdapter<T extends Q> extends ParseRecyclerQueryAdapter<T, QAdapter.MyViewHolder> {... }, yet this introduced another error saying that QAdapter did not implement onBindViewHolder even though it is implemented.
This may not work, but I would try replacing
public class QAdapter extends ParseRecyclerQueryAdapter<Q,QAdapter.MyViewHolder>{ ... }
with
public class QAdapter extends ParseRecyclerQueryAdapter<? extends Q,QAdapter.MyViewHolder>{ ... }
Try to replace
extends ParseRecyclerQueryAdapter<T, QAdapter.MyViewHolder> {... }
with
extends ParseRecyclerQueryAdapter<T extends ParseObject, QAdapter.MyViewHolder> {... }
This is how to make my ParseRecyclerQueryAdapter work
Well, as the old saying goes, "make sure everything is contiguous" or something like that. You've got a great idea for a abstract and you're doing it right, but maybe you've just got an inheritance issue by not having the same call issued by the same parameters as met by the processor. like <? extends Q,...> So in that case you've got to make sure it's all redundant. Good luck!
You should make your base class Q generic:
public abstract class Q<T extends Q<T>> extends ParseObject {
// some shared methods
public abstract ParseQuery<T> getQuery();
}
Then your class A becomes
#ParseClassName("A")
public class A extends Q<A> {
private static final A INSTANCE = new A();
#Override
public ParseQuery<A> getQuery() {
return ParseQuery.getQuery(A.class);
}
public static A getInstance(){
return INSTANCE;
}
}
and ParseQuery is:
public class ParseQuery<T> {
public static <T> ParseQuery<T> getQuery(Class<T> clazz) {
return null;
}
}
Related
I am following examples in "Effective Java" and came across the following code:
abstract static class Builder<T extends Builder<T>>
and its implementation:
public static class Builder extends Pizza.Builder<Builder>
Why is this declared T extends Builder<T> and not T extends Builder. Is it really needed to add the template <T>? What is the impact if I just use Builder<T extends Builder>?
It is called as "generic type". That declaration means T can be any type that is subclass of Builder<T>.
The goal of implementing Generics is finding bugs in compile-time other than in run-time. Finding bugs in compile-time can save time for debugging java program, because compile-time bugs are much easier to find and fix.
What is the impact if we just use Builder<T extends Builder>?
It transforms into raw type. And type safety goes off.
Builder<T extends Builder<T>> means that,
The class T passed in must implement the Builder interface / extend Builder class, and the generic parameter of Builder must be T itself.
I have some examples to show that actually the difference is not that big. I think the OP wants to know the difference between T extends Builder<T> and T extends Builder.
public abstract class Builder2<T extends Builder2> {
//doesn't compile either, because String is not a subtype of Builder2
static class WrongHouseBuilder extends Builder2<String> {}
//all ok
static class RawHouseBuilder extends Builder2 {}
static class HouseBuilder1 extends Builder2<RawHouseBuilder> {}
static class HouseBuilder2 extends Builder2<HouseBuilder1> {}
static class HouseBuilder3 extends Builder2<HouseBuilder2> {}}
Now with Builder<T>:
public abstract class Builder<T extends Builder<T>> {
//all ok
static class RawCarBuilder extends Builder {}
static class CarBuilder extends Builder<CarBuilder> {}
//ok as well, T doesn't have to be CarBuilder2
static class CarBuilder2 extends Builder<CarBuilder> {}
//doesn't compile because CarBuilder2 is not a subtype of Builder<CarBuilder2>
static class CarBuilder3 extends Builder<CarBuilder2> {}}
Of cause with T extends Builder<T>, you have more protection, but not that much.
UPDATE
Just to clarify, we should not use raw type. #Radiodef has provided an interesting example in the comment. And a quote from that answer to help you understand it:
In simpler terms, when a raw type is used, the constructors, instance methods and non-static fields are also erased.
Minor: It looks more natural to me to use Builder as an interface, not an abstract class. This is a sort of recursive type declaration. It is used for type safety to prevent nasty things like the following happens:
public abstract Builder<T extends Builder<T>> {
T build();
}
public class Entity extends Builder<String>{ // does not compile
#Override
public String build() {
return null;
}
}
public class Entity extends Builder<Entity>{ //ok
#Override
public Entity build() {
return null;
}
}
Anyway more naturally looking version (from my point of view) is:
public interface Buildable<T extends Buildable<T>> {
T build();
}
public final class Entity implements Buildable<Entity>{
//other methods
#Override
public Entity build() {
//implementation
}
}
I see that the question is about the <T> part in Builder<T>. Without this <T>, you simply get a raw type, and your IDE might complain.
But in my answer, I'd like to explain what's the purpose of T extends Builder<T>, because other answers do not seem to cover it (maybe you know this already).
T extends Builder<T> serves the purpose of returning appropriate Builder.this in all the Builder methods (except build() method, of course).
I usually use it with a protected abstract method like T thisInstance().
Example:
abstract class NamedBuilder<T extends NamedBuilder<T>> {
private String name;
T name(String name) {
this.name = name;
return thisInstance();
}
protected abstract T thisInstance();
}
final class MoreSpecificBuilder extends NamedBuilder<MoreSpecificBuilder> {
#Override
protected MoreSpecificBuilder thisInstance() {
return this;
}
}
Thanks to such approach, you do not have to redefine name() method in all the NamedBuilder subclasses to return the specific subclass.
Without such constraint type parameter T, you would have:
abstract class NamedBuilder {
NamedBuilder name(String name);
}
and you would need to override all such methods in subclasses like that:
final class MoreSpecificBuilder extends NamedBuilder {
#Override
MoreSpecificBuilder name(String name) {
super.name(name);
return this;
}
}
EDIT: Without the constraint extends Builder<T> on type parameter T:
abstract class NamedBuilder<T> {
// ...
}
this would work fine, although such design would be less intuitive and more error-prone.
Without such constraint, compiler would accept anything as T (e.g. String), so the constraint acts simply as a compile-time check for the implementors of NamedBuilder.
I have the following structure of classes and methods :
public class NavigationTree<T extends BaseListItem<? extends BaseData>> {
public boolean insert(final T parent, final T child){
}
}
public class Screen extends BaseData {
}
public class DrawerListItem<T> extends BaseListItem<T>{
}
This is what I am calling from one of my other classes :
mCurItems.insert(new DrawerListItem<Screen>(null, null),
new DrawerListItem<Screen>(screen.name, screen));
The compilers throws the following error :
Error: incompatible types: DrawerListItem cannot be converted to CAP#1 where CAP#1 is a fresh type-variable:CAP#1 extends BaseListItem from capture of ? extends BaseListItem
I do not understand why this should be wrong. DrawerListItem extends BaseListItem and Screen extends BaseData. I have tried reading the other posts around generic types and type params but none of them seem to address this issue.
Try this:
public class Test {
public static void main(String[] args) throws java.lang.Exception {
NavigationTree<DrawerListItem<Screen>> nt = new NavigationTree<>();
nt.insert(new DrawerListItem<Screen>(), new DrawerListItem<Screen>());
}
private static class NavigationTree<T extends BaseListItem<? extends BaseData>> {
public boolean insert(final T parent, final T child) {
return true;
}
}
private static class DrawerListItem<T> extends BaseListItem<T> {}
private static class BaseListItem<T> {}
private static class Screen extends BaseData {}
private static class BaseData {}
}
I figured out the solution. In my DrawerListItem declaration I had declared it as
public class DrawerListItem<T> extends BaseListItem<T>{
}
Whereas the NavigationTree was expecting:
<T extends BaseListItem<? extends BaseData>>
Which essentially means :
<DrawerListItem<? extends BaseData>>
in this case.
And hence the error was basically saying that the template type declared vs template type required are different and hence the error.
Hope this helps someone else.
Thanks everyone for the help!
I want to create object like belows :
private MyHashTable<AVLtree<TreeData>, TreeData> hashTable = new MyHashTable<>();
AVLtree and TreeData is what I defined, not java built in class.
But, I have no idea how to define MyHashTable class using generic.
What I can think about is
public class MyHashTable<S<T>,T> but it doesn't work.
You can declare like this
public class MyObject<T> {
}
public class MyHashTable<S extends MyObject<T>, T> {
}
In this case you can use
public class MyHashTable<S extends AVLTree<T>, T> {
}
Hope this help.
I have an interface:
public interface Human<D extends Details> {
D getDetails();
}
And a concrete impl:
public class Man implements Human<ManDetails> {
ManDetails getDetails();
}
I'd like to extend Man in such a way so I could do something like:
public class Baby extends Man {
BabyDetails getDetails();
}
So basically I'm looking for a way so Man would be concrete (I would be able to use it on it's own) but also a generic so others can extends it (for example, getDetails() of baby will get super.getDetails() and create a new instance of BabyDetails from it).
You may consider changing your code to
class Man<T extends ManDetails> implements Human<T> {
public T getDetails(){return null;}
}
which would let you do something like
class Baby extends Man<BabyDetails> {
public BabyDetails getDetails(){...}
}
or
class Baby<T extends BabyDetails> extends Man<T> {
public T getDetails(){...}
}
But as Sotirios Delimanolis already mentioned what you did is already fine
public class Baby extends Man {
public BabyDetails getDetails(){...}
}
because overriding method can declare new return type as long as this type is subtype of return type declared in overridden method, for instance
List<String> method()
can be overridden by
ArrayList<String> method();
I have the following class structure:
public class Team {
...
}
public class Event {
}
public abstract class Fixture<T extends Team> implements Event {
...
}
public abstract class Forecast<Event> {
}
public class MyPrediction<T extends Fixture<? extends Team>> extends Forecast<Fixture<? extends Team>>{
}
I am trying to model sports events of all kinds (i.e. a 'Fixture' is for a particular game between two participants play against each other, whereas another type of 'Event' may have many participants), along with predictions for the outcome of particular 'Events'. I have a generic method:
public <T> MyPrediction<Fixture<? extends Team>> getMyPrediction(Fixture<? extends Team> fixture) {
}
I want to be able to return a MyPrediction instance which has the generic type of the fixture argument, but I can't seem to do so. For example, if I do something like the following, then I get a compilation error:
SoccerFixture<EnglishSoccerTeams> soccerMatch = new ScoccerFixture<EnglishSoccerTeams>();
MyPrediction<SoccerFixture<EnglishSoccerTeams>> = getMyPrediction(soccerMatch);
I am willing to change my class structure to incorporate this feature. How can I do so?
Change the signature of getMyPrediction to
public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture)
This tells the compiler that the fixture types in the argument and result are the same, allowing type-checking to pass.
Here is a complete example, with some other minor changes to get it to compile. It introduces the class Predictor to hold the getMyPrediction method and a doit method to show sample use:
public interface Team {
}
public interface Event {
}
public abstract class Fixture<T extends Team> implements Event {
}
public abstract class Forecast<T> {
}
public class MyPrediction<T extends Fixture<? extends Team>> extends
Forecast<Fixture<? extends Team>> {
}
public class SoccerFixture<T extends SoccerTeam> extends Fixture<T> {
}
public class SoccerTeam implements Team {
}
public class EnglishSoccerTeam extends SoccerTeam {
}
public class Predictor {
public <T extends Fixture<? extends Team>> MyPrediction<T> getMyPrediction(T fixture) {
return new MyPrediction<T>();
}
public void doit() {
SoccerFixture<EnglishSoccerTeam> soccerMatch = new SoccerFixture<EnglishSoccerTeam>();
MyPrediction<SoccerFixture<EnglishSoccerTeam>> myPrediction = getMyPrediction(soccerMatch);
}
}
As noted elsewhere, you might need to introduce one or more factory objects to perform meaningful work in the MyPrediction implementation.
Java's type system is not powerful enough to do directly what you propose, because of type erasure (the generic parameters are not available at runtime.
The usual solution is to create a separate EventFactory class, which you can then pass in to any method which needs to create a specific Event subtype instance.