Can not cast class to generics in java - java

Please help resolve an issue regarding generics. I tried many ways but it's still not working.
Problem is:
public static void main(String[] args) {
Utils.execute(new TestAction(), new TestCallBack());
}
Compiler show error:
The method execute(Action<?>, CallBack<?,Action<?>>) in the type Utils is not applicable for the arguments (ImplementClass.TestAction, ImplementClass.TestCallBack)
My classes is:
Action class:
public abstract class Action<R> {
public R getResult() {
return null;
}
}
TestAction class is:
class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
Callback class is:
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);}
TestCallback class is:
class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
And Utils class is:
public class Utils {
public static void execute(Action<?> action, CallBack<?, Action<?>> callback) {
}
}
Thanks a lot.

The second parameter of the execute method is CallBack<?, Action<?>>, and Action there means the Action class itself, subclass of it is not allowed. What you need there is - ? extends Action<?>, which means either Action or some subclass of it.
Try changing the method signature -
public static void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
Note:
Generics are not co-variant. Take for example a method as follows -
static void method(List<Object> l) {}
And an invocation as follows is not allowed -
method(new ArrayList<String>());

You need to change two things,
TestCallBack should be like this -
public static class TestCallBack implements CallBack<String, Action<String>> {
#Override
public void onCall(Action<String> action) {
}
}
and, Utils should be like this -
public static class Utils {
// You need to ensure the same type, not just try and accept anything.
public static <T> void execute(Action<T> action, CallBack<?, Action<T>> callback) {
}
}
or using inner classes of a class called Question -
public abstract class Action<R> {
public R getResult() {
return null;
}
}
public class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);
}
public class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
public class Utils {
public void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
}
}
public static void main(String[] args) {
Question question = new Question();
question.new Utils().execute(question.new TestAction(), question.new TestCallBack());
}

Related

Uncheck conversion on returning class type

I have a method that returns a class type, and it is working right.
The problem is... I am getting some compilation warnings indicating unchecked conversion.
Below is the warning message I got:
Warning: java: getAjaxEventPayloadClass() in <anonymous com.iyotbihagay.wicket.panel.requestpage.resultlist.ResultList2$7> implements <P>getAjaxEventPayloadClass() in com.iyotbihagay.wicket.panel.paging.Paging.Support
return type requires unchecked conversion from java.lang.Class<com.iyotbihagay.wicket.support.RefreshSearchResultEventPayload> to java.lang.Class<P>
even if I use #SuppressWarnings("unchecked") I still cannot get rid of the compilation warning.
Below are some of the codes pointing to the warning:
ResultList2.java
public class ResultList2 {
...
private Component createPaging() {
return new Paging("paging", getRequestPageContext(), new Paging.Support() {
#Override
public void switchPage(AjaxRequestTarget target, int targetPageNum) {
getRequestPageContext().switchPage(target, targetPageNum);
}
#Override
public int getTotalNum() {
return getSearchResult().getTotalNum();
}
#Override
public int getPageSize() {
return getSearchResult().getPageSize();
}
#Override
public int getLastPageNum() {
return getSearchResult().getLastPageNum();
}
#Override
public int getCurrentPageNum() {
return getSearchResult().getCurrentPageNum();
}
#SuppressWarnings("unchecked")
#Override
public Class<RefreshSearchResultEventPayload> getAjaxEventPayloadClass() {
return RefreshSearchResultEventPayload.class;
}
#Override
public void decorateAjaxAttributes(AjaxRequestAttributes attributes, String pageNumMarkupId) {
decorateAjaxRefreshSearchResult(attributes, pageNumMarkupId);
}
});
}
...
}
Support.java
public static interface Support extends Serializable {
...
<P extends AjaxEventPayload> Class<P> getAjaxEventPayloadClass();
...
}
Paging.java
public class Paging {
...
private Support m_support;
...
#Override
public void onEvent(IEvent<?> event) {
super.onEvent(event);
WicketUtil.onEvent(event, m_support.getAjaxEventPayloadClass(), new AjaxEventHandler<AjaxEventPayload>() {
#Override
public void onEvent(IEvent<?> event, AjaxRequestTarget target, AjaxEventPayload paymentLoad) {
m_firstPageNumModel.detach();
m_previousPageNumModel.detach();
m_nextPageNumModel.detach();
m_lastPageNumModel.detach();
target.add(m_container);
}
});
}
...
}
WicketUtil.java
public class WicketUtil {
...
public static <P extends AjaxEventPayload> void onEvent(IEvent<?> event, Class<P> targetPayload, AjaxEventHandler<P> handler) {
if (event.getPayload() != null) {
if (targetPayload.isAssignableFrom(event.getPayload().getClass())) {
P p = (AjaxEventPayload)event.getPayload();
handler.onEvent(event, p.getTarget(), p);
}
}
}
...
}
m_support.getAjaxEventPayloadClass() is called/passed on WicketUtil.onEvent()... specifically on the second parameter.
RefreshSearchResultEventPayload is just one of the classes that extends AjaxEventPayload and there are other classes that extends to AjaxEventPayloadand are passed to WicketUtil.onEvent().
This should rather be:
public static interface Support extends Serializable {
...
Class<? extends AjaxEventPayload> getAjaxEventPayloadClass();
...
}
and
public class ResultList2 {
...
#Override
public Class<RefreshSearchResultEventPayload> getAjaxEventPayloadClass() {
return RefreshSearchResultEventPayload.class;
}
...
}
The reason is that <P extends AjaxEventPayload> means that the method can return a class of arbitrary payload type (as requested by the caller), e.g.:
support.<AjaxEventPayload>getAjaxEventPayloadClass()
instead of returning only the one payload type that is specific to the implementing class (e.g. RefreshSearchResultEventPayload).

Java - How to call method class with interface without know class name

I'm new in java, I want to call method class from implemented Class with interface without know class name "ClassA", which only know Object c and I have 2 file.
File (1) CobaInterface.java
package cobainterface;
public class CobaInterface {
public static void main(String[] args) {
ImplementedClass implementedClass = new ImplementedClass();
ClassA clsA = new ClassA();
implementedClass.myMethodFromClassA(clsA);
}
}
class ClassA{
public Integer getTwo(){
return 2;
}
}
interface MyInterface {
public void myMethod();
//here interface
public void myMethodFromClassA(Object c);
}
File (2) : ImpementedClass.java
package cobainterface;
public class ImplementedClass extends CobaInterface {
public void myMethodFromClassA(Object c) {
//System.out.println(c.getTwo()); <- wrong when call method c.getTwo()
}
}
How about if I want to call method getTwo() from ClassA without know Class Name, which only know Object c from file (2) as describe in code above. Thanks for advance.
You should use generic types so the implementation knows what the object will be,
interface MyInterface<T> {
public void myMethod();
//here interface
public void myMethodFromClassA(T c);
}
The impl becomes,
package cobainterface;
public class ImplementedClass Implements MyInterface<ClassA> {
public void myMethodFromClassA(ClassA c) {
//System.out.println(c.getTwo()); <- wrong when call method c.getTwo()
}
}
All together,
class Scratch {
public static void main(String[] args) {
ImplementedClass implementedClass = new ImplementedClass();
ClassA clsA = new ClassA();
implementedClass.myMethodFromClassA(clsA);
}
}
class ImplementedClass implements MyInterface<ClassA> {
#Override
public void myMethod() {
}
#Override
public void myMethodFromClassA(ClassA c) {
System.out.println(c.getTwo());
}
}
class ClassA {
public Integer getTwo() {
return 2;
}
}
interface MyInterface<T> {
void myMethod();
void myMethodFromClassA(T c);
}
You could also do a cast
System.out.println((MyClass)c.getTwo());
but you will lose all benefit of type saftey.

getThis() trick and ClassCastException

I've been wondering about the getThis() trick, and the alternative of the unsafe cast from a self-bounded type to its type parameter.
public abstract class SelfBound<T extends SelfBound<T>> {
protected abstract T getThis();
public void doSomething(T instance) { ... }
public final void doSomethingWithThis() { doSomething(getThis()); }
public final void doSomethingWithThisUnsafe() { doSomething((T) this); }
}
Is it possible to subclass SelfBound such that doSomethingWithThisUnsafe() throws a ClassCastException? (Is it possible to do this without subclassing SelfBound?)
Surely it's possible to have ClassCastException with subclassing. Here's a simple example:
public abstract class SelfBound<T extends SelfBound<T>> {
protected abstract T getThis();
public void doSomething(T instance) { }
public final void doSomethingWithThis() { doSomething(getThis()); }
public final void doSomethingWithThisUnsafe() { doSomething((T) this); }
public static class A extends SelfBound<A> {
#Override
protected A getThis() {
return this;
}
}
public static class B extends SelfBound<A> {
#Override
public void doSomething(A instance) {
super.doSomething(instance);
}
#Override
protected A getThis() {
return null;
}
}
public static void main(String[] args) {
new B().doSomethingWithThisUnsafe();
}
}
Output:
Exception in thread "main" java.lang.ClassCastException: SelfBound$B cannot be cast to SelfBound$A
at SelfBound$B.doSomething(SelfBound.java:1)
at SelfBound.doSomethingWithThisUnsafe(SelfBound.java:6)
at SelfBound.main(SelfBound.java:28)
It's not so clear what do you mean by "without subclassing SelfBound". As SelfBound is an abstract class, you cannot call its methods without subclassing it, thus you cannot have any exception when calling its methods.

Generics specific interface definition in Java

Is it possible to define following in Java:
public interface IGenericRepo<T> {
void add();
void delete();
void attach();
}
public interface IGenericRepo<Book> {
default String bookSpecificMethod(){
return "smthn";
}
}
public class NHGenericRepo<T> implements IGenericRepo<T>{
/* implementation */
}
public class NHUnitOfWork implements UnitOfWork{
#Autowired
public void setBookRepo(NHGenericRepo<Book> bookRepo) {
this.bookRepo= bookRepo;
}
public NHGenericRepo<Book> getBookRepo() {
return bookRepo;
}
private NHGenericRepo<Book> bookRepo;
}
And to be able somewhere in code to have:
{
#Autowired
public void setNhuw(NHUnitOfWork nhuw) {
this.nhuw = nhuw;
}
private NHUnitOfWork nhuw;
/**/
{
String st = this.nhuw.getBookRepo().bookSpecificMethod();
}
}
In .net this is possible by using Extension Method with "this IGenericRepo<Book>" as a first method parameter.
The closest you can come is:
public interface IBookGenericRepo extends IGenericRepo<Book> {
void BookSpecificMethod();
}

Correct usage of "<T extends SuperClass>"

I am not familiar with "Generics". Is it a correct use of "<T extends SuperClass>" ? And do you agree that the codes after using generics are better?
Before using Generics
=================================================
public abstract class SuperSample {
public void getSomething(boolean isProcessA) {
doProcessX();
if(isProcessA){
doProcessY(new SubASample());
}else{
doProcessY(new SubBSample());
}
}
protected abstract void doProcessX();
protected void doProcessY(SubASample subASample) {
// Nothing to do
}
protected void doProcessY(SubBSample subBSample) {
// Nothing to do
}
}
public class SubASample extends SuperSample {
#Override
protected void doProcessX() {
System.out.println("doProcessX in SubASample");
}
#Override
protected void doProcessY(SubASample subASample) {
System.out.println("doProcessY in SubASample");
}
}
public class Sample {
public static void main(String[] args) {
SubASample subASample = new SubASample();
subASample.getSomething(true);
}
}
After using Generics
=================================================
public abstract class SuperSample {
public void getSomething(boolean isProcessA) {
doProcessX();
if(isProcessA){
doProcessY(new SubASample());
}else{
doProcessY(new SubBSample());
}
}
protected abstract void doProcessX();
protected abstract <T extends SuperSample> void doProcessY(T subSample);
}
public class SubASample extends SuperSample {
#Override
protected void doProcessX() {
System.out.println("doProcessX in SubASample");
}
#Override
protected <T extends SuperSample> void doProcessY(T subSample) {
System.out.println("doProcessY in SubASample");
}
}
public class Sample {
public static void main(String[] args) {
SubASample subASample = new SubASample();
subASample.getSomething(true);
}
}
If you want to do what I think you want to do, I don't think that this is the right way (*). If you want that every subclass needs to implement a method that processes it's own type, then you can use the CRTP trick:
abstract class Super<S extends Super<S>> {
abstract void process(S s);
}
class SubA extends Super<SubA> {
void process(SubA s){ /* do something */ }
}
class SubB extends Super<SubB> {
void process(SubB s){ /* do something */ }
}
Note that this pattern enforces the generic signature of the subclasses, e.g. class SubA extends Super<SubB> wouldn't compile.
Java itself uses that trick in java.lang.Enum, by the way.
(*)If this is not the behavior you want to enforce, please clarify.
it's correct to use . It means that you restrict type T to be subclass of SuperSample. And for second answer, yes I think code with generecis is better because it keeps you from wrong casting of classes for example with containers (List ...). But in fact generics in Java are only syntax suger and so they are erased during runtime.

Categories

Resources