I've build the following case. An interface for all JAXBLists:
public interface JaxbList<T> {
public abstract List<T> getList();
}
And an base implementation:
#XmlRootElement(name="list")
public class JaxbBaseList<T> implements JaxbList<T>{
protected List<T> list;
public JaxbBaseList(){}
public JaxbBaseList(List<T> list){
this.list=list;
}
#XmlElement(name="item" )
public List<T> getList(){
return list;
}
}
As well as an implementation for a list of URIs:
#XmlRootElement(name="uris")
public class JaxbUriList2 extends JaxbBaseList<String> {
public JaxbUriList2() { super(); }
public JaxbUriList2(List<String> list){
super(list);
}
#Override
#XmlElement(name="uri")
public List<String> getList() {
return list;
}
}
And I'm using the List in the following way:
public JaxbList<String> init(#QueryParam("amount") int amount){
List<String> entityList = new Vector<String>();
...
enityList.add("http://uri");
...
return new JaxbUriList2(entityList);
}
I thought the output should be:
<uris>
<uri>
http://uri
</uri>
...
</uris>
But it is something like this:
<uris>
<item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">
http://uri
</item>
...
<uri>
http://uri
</uri>
...
</uris>
I think it has something to do with the inheritance, but I don't get it...
What's the problem? - How can I fix it?
Thanks in advance!
Annotations are obtained through reflection. The annotation is bound to the type it's defined in.
public class AnnotationTest {
public static class A
{
#XmlElement(name="item")
public void doIt() { }
}
public static class B extends A
{
#XmlElement(name="name")
public void doIt() { }
}
public static void main(String[] args)
{
B b = new B();
Method m = b.getClass().getMethods()[0];
Annotation[] ann = m.getDeclaredAnnotations();
System.out.println( ann.length ); // prints 1
}
}
So this behavior is not due to the reflection mechanism itself. It seems like the JAXB framework does explicitly list the annotation on the method in the class and the super classes. Surprisingly this still works, but not as you would like.
Can't you just remove #XmlElement(name="item") in the base class?
EDIT
According to your comment (but still not sure if I understand all correctly), I would suggest:
#XmlRootElement(name="list")
public class JaxbBaseList<T> implements JaxbList<T>{
protected List<T> list;
public List<T> getList(){
return list;
}
}
public class JaxbPrimitiveList<T> extends JaxbList<T>{
protected List<T> list;
#XmlElement( name="item" )
public List<T> getList(){
return list;
}
}
#XmlSeeAlso( Uri )
public class JaxbUriList<Uri> extends JaxbList<Uri>{
protected List<Uri> list;
#XmlElement( name="uri" )
public List<Uri> getList(){
return list;
}
}
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);
}
}
I'm trying to define an abstract class that takes in a List of things and does stuff. Something like:
abstract public class AbstractClass {
private final List<?> list;
public AbstractClass(List<?> list) {
this.list = list;
}
public List<?> getList() { return list; }
abstract void addToList(List<?> list);
}
public class Class1 extends AbstractClass {
public Class1(List<Integer> list) {
super(list);
}
#Override
void addToList(List<Integer> list) {
// do stuff
}
}
public class Class2 extends AbstractClass {
public Class2(List<String> list) {
super(list);
}
#Override
void addToList(List<String> list) {
// do stuff
}
}
List<Integer> a = new List<Integer>();
Class1 c1 = new Class1(a);
List<Integer> b = c1.getList();
c1.addToList(a);
List<String> c = new List<String>();
Class2 c2 = new Class2(c);
List<Integer> d = c2.getList();
c2.addToList(c);
Having addToList with specific types in the subclasses is generating errors, but I don't know if that's a matter of syntax (with my poor knowledge of generics) or what I'm trying to do itself (is it possible to overload an abstract method like that)?
You should make AbstractClass a typed class instead of using the ? wildcard.
abstract public class AbstractClass<T> {
private final List<T> list;
public AbstractClass(List<T> list) {
this.list = list;
}
public List<T> getList() { return list; }
abstract void addToList(List<T> list);
}
In this case, you would have
public class Class1 extends AbstractClass<Integer> { ... }
public class Class2 extends AbstractClass<String> { ... }
I have these classes:
class Parent {
public Parent() {
}
}
class ChildA extends Parent {
public ChildA() {
super();
}
}
class ChildB extends Parent {
public ChildB() {
super();
}
}
public ListClas(List(Parent) list) {
this.list=list;
}
}
And I want to run ListClas constructor as below.
List<ChildA> list_childA = new ArrayList<ChildA>();
List<ChildB> list_childB = new ArrayList<ChildB>();
ListClas listClasA = new ListClas(list_childA);
ListClas listClasB = new ListClas(list_childB);
But the compiler throws an error. How do I do this correctly using polymorphism?
If you want a function that accepts List containing subclasses of a superclass you should use syntax.
public ListClas(List<? extends Parent> list){
this.list=list;
}
It will accept both of them.
ListClas listClasA = new ListClas(list_childA);
ListClas listClasB = new ListClas(list_childB);
If you change to List<? extends Parent> list (also change ListClas.list field definition) in your ListClas then it will compile and work.
All of them: List<Parent>, List<ChildA> and List<ChildB> are different concrete parameterized type.
You can read more about this here: https://stackoverflow.com/a/20940807/516167
I think you want your ListClas to look something like this:
class ListClas<T>
{
private List<T> list;
public ListClas(List<T> list)
{
this.list = list;
}
}
Then to create them:
ListClas<ChildA> listClasA = new ListClas<ChildA>(list_childA);
ListClas<ChildB> listClasB = new ListClas<ChildB>(list_childB);
The T is a generic type designation. It allows you to use the same class for multiple runtime types. So you can do the above instead of having to write this:
class AListClas
{
private List<ChildA> list;
public AListClas(List<ChildA> list)
{
this.list = list;
}
}
class BListClas
{
private List<ChildB> list;
public BListClas(List<ChildB> list)
{
this.list = list;
}
}
If you don't need quite as much flexibility you could write your ListClas like this:
class ListClas
{
private List<? extends Parent> list;
public ListClas(List<? extends Parent> list)
{
this.list = list;
}
}
and use it like this:
ListClas listClasA = new ListClas(list_childA);
ListClas listClasB = new ListClas(list_childB);
I'm working in a Genetic Algorithm and I want it as abstract as possible to be able to reuse the GA. I defined and implemented a Population Interface, and well it works, but I'm sure that's not the best way to do it. I don't have great experience with Java Generics. Is there an easier way of defining and implementing the Population interface (e.g. maybe avoid a cast conversion? avoid a new list in getChromosomes() ?)
public interface Population
{
void addChromosomes(List<? extends Chromosome> chromosomes);
List<Chromosome> getChromosomes();
// More code here ...
}
public class TSPPopulation implements Population
{
private List<TSPChromosome> chromosomes;
#Override
public void addChromosomes(List<? extends Chromosome> chromosomes) {
for (Chromosome chromosome : chromosomes) {
this.chromosomes.add((TSPChromosome) chromosome);
}
}
#Override
public List<Chromosome> getChromosomes() {
List<Chromosome> newList = new ArrayList<Chromosome>();
for (TSPChromosome chromosome : chromosomes) {
newList.add(chromosome);
}
return newList;
}
}
Use a Bounded Wildcard in your interface:
public interface Population<T extends Chromosome>{
void addChromosomes(List<T> chromosomes);
List<T> getChromosomes();
}
public class TSPPopulation implements Population<TSPChromosome>
{
private List<TSPChromosome> chromosomes;
#Override
public void addChromosomes(List<TSPChromosome> chromosomes) {
...
}
#Override
public List<TSPChromosome> getChromosomes() {
...
}
}
The simplest solution is extending a list (then use addAll(...) to add a list of Chromosoms to the list):
class Population<T extends Chromosome> extends ArrayList<T> {
}
But if you want the same structure I would make Population into a generic list class. That way both add... and get... methods can be handled in the generic base class. If you do want to override any other feature you just extend Population (class TSPPopulation extends Population<TSPChromosome>.
Usage:
public static void main(String... args) {
Population<TSPChromosome> tspPopulation = new Population<TSPChromosome>();
...
}
Implementation:
class Population<T extends Chromosome> {
private List<T> chromosomes = new ArrayList<T>();
public void addChromosomes(List<T> chromosomes) {
this.chromosomes.addAll(chromosomes);
}
public List<T> getChromosomes() {
return new ArrayList<T>(this.chromosomes);
}
}
It would be much safer if you made the Population generic itself:
public interface Population<T extends Chromosome> {
void addChromosomes(List<T> chromosomes);
List<T> getChromosomes();
}
public class TspPopulation implements Population<TspChromosome>{
#Override
public void addChromosomes(List<TspChromosome> chromosomes){
//
}
#Override
public List<TspChromosome> getChromosomes(){
//
}
}
That way you would not need any casting in client code.
I know GAs, and I would question whether your Population implementation actually needs to know which kind of Chromosome you put in. Do you really have different Population implementations depending on the Chromosome subclass? Or what you really want is to make sure you have the same subclass of Chromosome in a Population? In this last case, you can define the Population interface as others suggested, and the make a generic implementation (or skip the interface altogether):
public class PopulationImpl implements Population<T extends Chromosome> {
private List<T> chromosomes;
#Override
public void addChromosomes(List<T> chromosomes) {
this.chromosomes.addAll(chromosomes);
}
#Override
public List<T> getChromosomes() {
return new ArrayList<T>(chromosomes);
}
}
Be careful not to put too many generics, or you will end up with generics hell, or tons of casts which will make generics more annoying than useful.
Yes, for instance:
public interface Population<T extends Chromosome>
{
void addChromosomes(List<T> chromosomes);
List<T> getChromosomes();
// More code here ...
}
public class TSPPopulation implements Population<TSPChromosome>
{
private List<TSPChromosome> chromosomes;
#Override
public void addChromosomes(List<TSPChromosome> chromosomes) {
this.chromosomes.addAll(chromosomes);
}
#Override
public List<TSPChromosome> getChromosomes() {
return new ArrayList<TSPChromosome>(chromosomes);
}
}