NoSuchFieldError when extending Interface in generic class - java

I have a bean ArtistEntityBean extending GenericEntityBean:
public class ArtistEntityBean extends GenericEntityBean<Artist> {
public ArtistEntityBean() {
item = new Artist();
}
}
-
public abstract class GenericEntityBean<T extends IntEntity> implements Serializable {
protected T item;
public void init(Integer id){
item.setId(id);
}
}
-
public class Artist extends ArtistBaseEntity implements Comparable<Artist> {
...
}
-
public abstract class ArtistBaseEntity implements IntEntity {
...
}
-
public interface IntEntity {
Integer getId();
void setId(Integer id);
}
-
I'm trying to put as much code as possible in the GenericEntityBean class, which is why I thought of using an interface in order to be able to set the id of the item.
This does not work tough, as I get a NoSuchFieldError in the constructor of ArtistEntityBean and I don't know why?

If item is public, protected or default you have to use
super.item = new Artist();
in the constructor of ArtistEntityBean.
If it is private you have to provide a setter method in the abstract class.
Edit: If you did not specify item in the abstract class then do the following
public abstract class GenericEntityBean<T extends IntEntity> implements Serializable {
protected T item;
public void init(Integer id){
item.setId(id);
}
}

Related

How to get the class of the genereric parameter of a Interface from the interface

I have this Interface:
public interface Test<T> {
default Class<?> getT() {
return T.getClass(); < --error
}
}
next i have a class that implements it:
static class ItemService implements Test<Item>{
}
And i want to get the 'Item' class from the 'ItemService' class
static ItemService service = new ItemService();
private static void k() {
System.out.println(service.getT());
}
Now one way to do it is this:
public interface Test<T> {
default Class<?> getT() {
return Type.type;
}
class Type {
public static Class<?> type;
}
}
Service:
static class ItemService implements Test<Item> {
public ItemService() {
Type.type = Item.class;
}
}
And it works fine but there is a problem,
When another class implement the interface:
static class OrderService implements Test<Order> {
public OrderService() {
Type.type = Order.class;
}
}
And i try:
static ItemService service = new ItemService();
static OrderService orderservice = new OrderService();
private static void k() {
System.out.println(service.getT());
}
I get the Order class and not the Item class
How can i make it work?
Classes inside interfaces are static, You can remove the default from the function and every class will need to implement this. example:
public interface Test<T> {
public Class<T> getT();
}
static class ItemService implements Test<Item> {
public Class<Item> getT() {return Item.class;}
}
static class OrderService implements Test<Order>{
public Class<Order> getT() {return Order.class;}
}
An alternative could be an abstract class.
public interface Test<T> {
public Class<T> getT();
}
abstract class AbstractTest<T> implements Test<T> {
private final Class<T> type;
AbstractItemService(Class<T> type) { this.type = type }
public Class<T> getT() {return type;}
}
class ItemService extends AbstractTest<Item> {
ItemService() { super(Item.class); }
// implement other things
}
class OrderService extends AbstractTest<Order>{
OrderService() { super(Order.class); }
// implement other things
}
Here is another option, if your implementation has an instance of T.
interface Test<T>{
T getT();
default Class<?> getClassOfT(){
return getT().getClass();
}
}

Confused by <T extends Class> behavior

So I have this AbstractBook Class
public abstract class AbstractBook<T extends AbstractPage> implements Serializable{
public AbstractBook() {
}
public abstract void addPage(T var1);
}
and I have a sub class:
public class Book extends AbstractBook {
private ArrayList<Page> allPages;
private String title;
Book(String title){
allPages = new ArrayList<Page>();
}
#Override /** Doesn't Work */
public void addPage(Page page) {
this.allPages.add();
}
}
In the subclass addPage method, I can't Override the method in the given form, because the parameter asks to be an AbstractPage type, even though Page is extended from AbstractPage:
public abstract class AbstractPage implements Serializable {
public AbstractPage() {
}
}
and
public class Page extends AbstractPage {
private String content;
public Page(String Content){
this.content = Content;
}
}
Why is that exactly?
Isn't T defined as <T extends AbstractPage>, thus, Page should be an acceptable type for the parameter in addPage method ? It insists on compiler insists on AbstractPage type.
Or does <T extends AbstractPage> not actually apply to the T var1
in the addPage method ?
But even then, what stops addPage(Page page) method from compiling?
You are extending a raw type.
Change
public class Book extends AbstractBook
to
public class Book extends AbstractBook<Page>
Besides, this.allPages.add(); should probably be this.allPages.add(page);.

meaning of "public interface MyInterface<T extends MyInterface<T>> {...}"

I have just come across a piece of code which does:
public interface MyInterface<T extends MyInterface<T>> {...}
Then classes seem to do:
public final class MyClass implements MyInterface<MyClass> {...}
The interface has no definitions, only method declarations. I think extends MyInterface<T> is redundant and the interface can be just:
public interface MyInterface<T> {...}
Being new to Java, is there any purpose of the original interface definition (with the extends part)? Is this a pattern?
The interface has no definitions, only method declarations. I think extends MyInterface is redundant...
No it's not. The bound ensures that only Classes are accepted that implement this interface as well. Let's take a look at an interface:
SomeInterface.java
public interface SomeInterface<T extends SomeInterface<T>>
{
public T getInterfaceImpl();
public void setTitle(String text);
}
and two differnet implementing classes:
SomeInterfaceImpl.java:
public class SomeInterfaceImpl implements SomeInterface<SomeInterfaceImpl>
{
private String title;
#Override
public SomeInterfaceImpl getInterfaceImpl()
{
return new SomeInterfaceImpl();
}
#Override
public void setTitle( String text )
{
this.title = text;
}
}
and AnotherSomeInterfaceImpl.java:
public class AnotherSomeInterfaceImpl implements SomeInterface<SomeInterfaceImpl>
{
private String title;
#Override
public SomeInterfaceImpl getInterfaceImpl()
{
return new SomeInterfaceImpl();
}
#Override
public void setTitle( String text )
{
this.title = text;
}
}
Take a precise look at the method signature in both implementations. Both classes extend the same interface with the same type parameter which defines the signature of the methods in the same way. Imagine omitting the bound in the interface delcaration. Suddenly an implementing class could look like this:
public class AnotherSomeInterfaceImpl implements SomeInterface<String>
{
private String title;
#Override
public String getInterfaceImpl()
{
return "Hello World";
}
#Override
public void setTitle( String text )
{
this.title = text;
}
}
And now we are no longer assured that the returned object of public T getInterfaceImpl() is an implementation of SomeInterface or that it has methods like public void setTitle(String text).

MainActivity must be declared abstract or implement interface X

I have the interface
public interface MyInterface {
public void myTask (ServiceHandler.SongInfo[] songInfo);
}
I have the ServiceHandler.SongInfo class
public class SongInfo {
public String wrapperType;
public String kind;
public Integer artistId;
public Integer collectionId
//etc
}
I have the decleration
public class MainActivity extends AppCompatActivity implements MyInterface {
//... Everything else
#Override
void myTask(SongInfo[] songInfo){
}
}
But I sill get the error unless I comment out this line in my interface
public interface MyInterface {
//public void myTask (ServiceHandler.SongInfo[] songInfo);
}
What does it mean?
Change songInfo[] to ServiceHandler.SongInfo[] in the implementation argument

Typed generic DAO and Entity

currently I'm trying to implement a typed generic DAO.
I do not even get to compile anything, since NetBeans complains about UserDAOHibernate
interface expected here
type argument User is not within bounds of type-variable ENTITY
I'm afraid there is some obvious mistake in how I use inheritance/interfaces, since I'm rather new to Java.
Here's some stripped down code
public interface GenericEntity<ID extends Serializable> {
public abstract ID getId();
public abstract void setId(final ID id);
}
public abstract class LongEntity implements GenericEntity<Long> {
protected Long id;
public Long getId();
public void setId(final Long id);
}
public class User extends LongEntity implements Serializable {
private String name;
private String password;
private Customer customer;
}
public interface GenericDAO<ENTITY extends GenericEntity<ID>, ID extends Serializable> {
public abstract ENTITY findById(ID id);
public abstract List<ENTITY> findAll();
public abstract ENTITY makePersistent(ENTITY entity);
public abstract void makeTransient(ENTITY entity);
}
public abstract class GenericHibernateDAO<ENTITY extends GenericEntity<ID>, ID extends Serializable>
implements GenericDAO<ENTITY, ID> {
}
public class UserDAOHibernate implements GenericHibernateDAO<User, LongEntity> {
}
Is it that LongEntity should extend GenericEntity<Long>? If so, how would I do this with Java's single level or inheritance?
Is this layered approach a bad example to follow? All my entities need an id and this implementation could easily be reused lateron with different id types, so I thought I might use it.
The error comes from here:
public class UserDAOHibernate implements GenericHibernateDAO<User, LongEntity> {
}
You've specified that GenericHibernateDAO's ID parameterized type is bounded by <ID extends Serializable>.
LongEntity extends GenericEntity, and hence, why you have a type mismatch.
Also, GenericHibernateDAO is an abstract class (and not an interface), so you'll need to extends instead of implements.
The correct solution should be:
public class UserDAOHibernate extends GenericHibernateDAO<User, Long> {
}

Categories