i get a Java type mismatch at the following code. For a better reading i skipped the class bodies.
class Main{
//interface
public interface HasDeletedFlag {
public boolean deleted_flag();
}
//classes
public abstract class Entity<? extends Entity.Factory<E, ?>>> {
...
}
public class Select{
...
public <E extends Entity<? extends Entity.Factory<E, ?>>> List<E> search (E.Factory<E,?> result_factory){
...
}
}
public static class Person extends Entity<Person.$.Factory>
implements HasDeletedFlag {
...
public static class $ {
public static class Factory
extends Entity.Factory<Person,Factory>{
...
}
}
}
static class Database{
...
public final Person.$.Factory person = new Person.$.Factory();
}
//method
private <E extends Entity<?> & HasDeletedFlag> List<E> findEntity(String id){
...
Database db = new Database();
List<E> objects = new ArrayList<E>();
Select query = new Select();
objects = query.<Person>search(db.person);
}
}
In the following line i get the class mismatch error:
objects = query.<Person>search(db.person);
If i add a class cast like (List<E>) the error disappears, but in my understanding the type Person matches the type E.
Greetings
Goetz
Related
I am trying to build one page assembler using generic approach. Following is piece of code.
In this code IEntity is marker interface for DB entities.
public abstract class PageHrefBuilder implements HrefBuilder<IEntity, PageLinks> {
#Override
public PageLinks buildLinks(IEntity entity) {
return null;
}
}
public interface HrefBuilder<E extends IEntity, L extends Links> {
public L buildLinks(E dto);
}
So we have one interface says can build links using IEntity type of class and return Links type of value. So I want to write some common code in abstract class and abstract class does not know what type entity it suppose to deal with.
For example entity can UserEntity, OrderEntity and so on.
So my question is how in abstract class I can get the class instance to build links with using instanceof or if else approach.
Could someone help me on this.
You can make your buildLinks method to take Class<T> parameter instead of the object you have to pass.
so it will be
public L buildLinks(Class<E> dto);
then in your abstract class
#Override
public PageLinks buildLinks(Class<IEntity> dto) {
return dto.newInstance();
}
Hope this answer could help you.
This got a bit over-engineered but it works and all generics are proper. Hopefully it shows you how you can build your solution:
public class GenericsSample {
public abstract class Links {
String data;
public Links(String data) {
this.data = data;
}
}
public class UserLinks extends Links {
public UserLinks(String data) {
super(data);
}
}
public class PageLinks extends Links {
public PageLinks(String data) {
super(data);
}
}
public abstract class IEntity<L extends Links> {
public abstract L buildLinks();
}
public class UserEntity extends IEntity<UserLinks> {
#Override
public UserLinks buildLinks() {
return new UserLinks("From UserEntity");
}
}
public class PageEntity extends IEntity<PageLinks> {
#Override
public PageLinks buildLinks() {
return new PageLinks("From PageEntity");
}
}
public interface HrefBuilderInterface<E extends IEntity<L>, L extends Links> {
public L buildLinks(E dto);
}
public class HrefBuilder<E extends IEntity<L>, L extends Links> implements HrefBuilderInterface<E, L> {
#Override
public L buildLinks(E entity) {
return entity.buildLinks();
}
}
public static void main(String[] args) {
new GenericsSample().go();
}
private void go() {
System.out.println(new HrefBuilder<UserEntity, UserLinks>().buildLinks(new UserEntity()).data);
System.out.println(new HrefBuilder<PageEntity, PageLinks>().buildLinks(new PageEntity()).data);
}
}
Also note that thanks to this setup the following is not valid:
System.out.println(new HrefBuilder<PageEntity, PageLinks>().buildLinks(new UserEntity()).data);
You can declare abstract method in abstract class to get new instance of Links interface:
abstract class PageHrefBuilder<E extends IEntity, L extends Links> implements HrefBuilder<E, L> {
#Override
public L buildLinks(E dto) {
L links = newLinks();
// ...
return links;
}
protected abstract L newLinks();
}
and implement getting new instance in realization.
I am trying to make a generic handling of different service implementations and I constantly receive the "Unchecked call due to raw type" error.
I have tried several implementations, but could not quite understand what is the issue here.
I have the following model:
public abstract class Fruit {
public List<String> vitamins;
public String originCountry;
// getters and setters omitted
}
The concrete implementation are the following:
public class Kiwi extends Fruit {
}
public class Pineapple extends Fruit {
}
I have the following interface:
public interface FruitCheckService<T extends Fruit> {
List<String> compareVitaminsFromDifferentCountries(T firstFruit, T secondFruit);
Class<T> getImplementation();
}
With implementations for the 2 models given above:
#Service
public class KiwiCheckServiceImpl implements FruitCheckService<Kiwi> {
#Override
public List<String> compareVitaminsFromDifferentCountries(Kiwi firstFruit, Kiwi secondFruit) {
// some implementation
return new ArrayList<>();
}
#Override
public Class<Kiwi> getImplementation() {
return Kiwi.class;
}
}
And pineapple:
#Service
public class PineappleCheckServiceImpl implements FruitCheckService<Pineapple> {
#Override
public List<String> compareVitaminsFromDifferentCountries(Pineapple firstFruit, Pineapple secondFruit) {
// some implementation
return new ArrayList<>();
}
#Override
public Class<Pineapple> getImplementation() {
return Pineapple.class;
}
}
I have the following class which is manupulating with the different beans:
#Service
public class FruitServices {
private Map<Class, FruitCheckService> beansMap;
#Autowired
public FruitServices(List<FruitCheckService> fruitCheckServices) {
beansMap = new HashMap<>();
fruitCheckServices
.forEach(
fruitCheckService -> {
Class implementation = fruitCheckService.getImplementation();
beansMap.put(implementation, fruitCheckService);
}
);
}
public FruitCheckService getFruitCheckService(Class clazz) {
return beansMap.get(clazz);
}
}
At the end, this is the service where I am calling this:
#Component
public class BusinessService {
#Autowired
private FruitServices fruitServices;
public void compareVitamins(Fruit one, Fruit two) {
Class<? extends Fruit> aClass = one.getClass();
FruitCheckService fruitCheckService = fruitServices.getFruitCheckService(aClass);
List<String> result = fruitCheckService.compareVitaminsFromDifferentCountries(one, two);
}
}
How to use correctly the fruitCheckService without receiving "Unchecked call to 'compareVitaminsFromDifferentCountries(T, T)' as a member of raw type 'exercise2.service.FruitCheckService'"?
The problem is that you are using the raw type Class in your service definition. To get around this problem, you can use the bounded wildcard type ?, as such:
class FruitServices {
private Map<Class<? extends Fruit>, FruitCheckService<? extends Fruit>> beansMap;
public FruitServices(List<FruitCheckService<? extends Fruit>> fruitCheckServices) {
beansMap = new HashMap<>();
fruitCheckServices
.forEach(
fruitCheckService -> {
Class<? extends Fruit> implementation = fruitCheckService.getImplementation();
beansMap.put(implementation, fruitCheckService);
}
);
}
public FruitCheckService<? extends Fruit> getFruitCheckService(Class<? extends Fruit> clazz) {
return beansMap.get(clazz);
}
}
For class BusinessService things are going to be trickier. First, it is necessary to make compareVitamins a generic method to ensure both fruits are of the same type. But even then, I don't believe you can avoid an unchecked cast from the result of getFruitCheckService because, as FruitServices has to deal with services for different types of fruit, you can't have a precise type parameter for the return value of getFruitCheckService.
class BusinessService {
private FruitServices fruitServices;
public <T extends Fruit> void compareVitamins(T one, T two) {
#SuppressWarnings("unchecked")
FruitCheckService<T> fruitCheckService =
(FruitCheckService<T>) fruitServices.getFruitCheckService(one.getClass());
List<String> result = fruitCheckService.compareVitaminsFromDifferentCountries(one, two);
}
}
The idea is make ExporParts function in Export Class works with any WebData derivative. To do that I need to know the T type class and it name.
The solution proposed works, but I have to write it manually. I was wondering if possible know the class name only with the current information about the type.
In the other hand, reflection is not an option. Too expensive.
Thanks.
Example
// Data gathered at runtime, may be other derivative class
WebData data = new BikeModel();
Webdata data2 = new FooModel();
BikeParser parser = new BikeParser();
FooParser parser2 = new FooParser();
// Should be BikeModel, FooModel
Class<?> returnedtype = parser.GetreturnType();
Class<?> returnedtype2 = parser2.GetreturnType();
// Exporter algorithms wrapper
Exporter exporter = new Exporter();
exporter.SetExporter("BikeExporter",returnedtype);
// Finally export data
exporter.ExportData(data);
// Works too
exporter.SetExporter("FooExporter",returnedtype2);
exporter.ExportData(data2);
Implementation:
public abstract class WebData { ... }
// Data models
public class BikeModel extends WebData { ... }
public class FooModel extends WebData { ... }
public interface IParser <T extends WebData>
{
T ParseData();
Class<T> GetReturnType();
}
// Concrete class
public class BikeParser implements IParser<BikeModel>
{
#Override
public BikeModel ParseData() { ... }
#Override
public Class<BikeModel> GetReturnType()
{
return BikeModel.class;
}
// interface to export diferent types of data
// BikeModel, FooModel, etc.
public interface IExporter<T extends WebData>
{
void ExporParts(T data);
}
// Concrete Exporters
public class BikeExporter implements IExporter<BikeModel> { ... }
public class FooExporter implements IExporter<FooModel> { ... }
public class Exporter
{
private IExporter exporter;
public void SetExporter(String name, Class<T extends WebData> type)
{
exporter = ExporterFactory.GetExporter(name,type)
}
public <T extends WebData> void ExporParts(T data)
{
Class<T> c = (Class<T>) data.getClass();
exporter.ExporParts(c.cast(data));
}
}
I think you're just looking for a class literal:
#Override
public Class<BikeModel> GetReturnType()
{
return BikeModel.class;
}
Let me show my quick example:
public class Main {
public static abstract class Food {
}
public static abstract class Fruit extends Food {
public String getJuice(){
return "juice";
}
}
public static abstract class Container<T extends Food> {
private T food;
public final T get(){
return food;
}
}
public static abstract class Crate<T extends Fruit> extends Container<T> {
}
public static void Bar(Crate crate) {
Food f = crate.get(); //compiles fine
//Fruit f2 = crate.get(); //can't compile
}
}
When given a raw type, crate.get() returns Food instead of Fruit
note: Crate is declared as Crate<T extends Fruit> extends Container<T> so Crate<Food> is forbidden.
I am just curious: why does the method T get() not return Fruit? Why is Crate<Fruit> required?
This happens because get is declared by Container. When using the raw type Crate, which has the effect of applying erasure to all of its (inherited) methods, the signature of public T get() is erased to public Food get(), because T has an upper bound of Food in its declaring class.
While Crate narrows the upper bound of T, which happens to be the return type of get, it doesn't override that method. If that were the case, you would see different behavior:
public static abstract class Container<T extends Food> {
private T food;
public T get() {
return food;
}
}
public static abstract class Crate<T extends Fruit> extends Container<T> {
#Override
public T get() {
return super.get();
}
}
public static void bar(Crate crate) {
Food f = crate.get(); // compiles fine
Fruit f2 = crate.get(); // also compiles
}
Now, public T get() is erased to public Fruit get(), since it has been redeclared in a class where T has an upper bound of Fruit.
What should be the signature of a method that takes a generic object and returns another generic object, one that either is the same or a sub class of the original class? That is, if the method takes some generic class A, the returned object is guaranteed to be either A or B such that B extends A (directly or indirectly)?
The code below exemplifies what I'm trying to do, in the function getList():
package com.company;
import java.util.ArrayList;
public class Main {
private Main(){
List<String> stringList = new GenericMessageListCreator.getList(StringGenericMessage.class);
}
private class GenericMessageListCreator() {
public List<GenericMessage<T1>> getList(Class<T1 extends GenericMessage> clazz) {
return new ArrayList<T1>();
}
}
private class GenericMessage<T> {
public GenericMessage(){};
private T internalValue;
public void setValue(T value) {
this.internalValue = value;
}
public void echoValue() {
System.out.println("I contain " + internalValue);
}
}
private class StringMessage extends GenericMessage<String>{}
private class IntegerMessage extends GenericMessage<Integer>{}
}
Example aside, in actuality I'm writing a registry of classes that are used for Commands in a command pattern. When I get an object by its class I want to fetch the appropriate Command and pass the object to it.
I think you are looking for this signature:
public <T1 extends GenericMessage> List<GenericMessage<T1>> getList(Class<T1> clazz) {
return new ArrayList<T1>();
}
You'll find more info about generic methods here.
EDIT
Based on what I understand from your sample code, I would go for something like (I corrected some syntax errors in your code):
private class GenericMessageListCreator {
public <U, V extends GenericMessage<U>> List<U> getList(Class<V> clazz){
return new ArrayList<U>();
}
}
private class GenericMessage<T> {
public GenericMessage(){};
private T internalValue;
public void setValue(T value)
{
this.internalValue = value;
}
public void echoValue() {
System.out.println("I contain " + internalValue);
}
}
private class StringMessage extends GenericMessage<String>{}
private class IntegerMessage extends GenericMessage<Integer>{}
Thus, you'll be able to create a List<String from `StringMessage like this:
List<String> stringList = new GenericMessageListCreator().getList(StringMessage.class);
I'm not even sure which method you want to have this behavious on, but I've assuming it's getList():
private class GenericMessageListCreator() {
public <T extends GenericMessage<?>> List<T> getList(Class<T> clazz) {
return new ArrayList<T>();
}
}