This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
Please, help to understand what is wrong in next code, since I have pretty modest knowledge in Java generics.
Can't find out why I getting pageData is null in class BPage, when in APage it's fine. Thanks in advance.
I've simplified the excample classes to several rows:
public abstract class PageData {
}
public abstract class Page<T extends PageData> {
protected T pageData;
public Page(T pageData) {
this.pageData = pageData;
}
}
public class APageData extends PageData {
public final String locator = "//*[#id=\"id_1\"]";
}
public class APage<T extends APageData> extends Page<APageData> {
public APage(T pageData) {
super(pageData);
}
public void getLocator() {
System.out.println(pageData.locator);
}
}
public class BPageData extends APageData {
public final String locator = "//*[#class=\"class_1\"]";
}
public class BPage extends APage<BPageData> {
public BPage(BPageData pageData) {
super(pageData);
}
}
APage aPage = new APage(new APageData());
aPage.getLocator(); // locator found, OK
BPage bPage = new BPage(new BPageData());
bPage.getLocator(); //pageData NullPointerException
You need to tell the super what to do
public class BPage extends APage<BPageData> {
public BPage(BPageData pageData) {
super(pageData);
//this.pageData = pageData;
}
}
Related
I have problem with understanding how Java wildcard works in one particular case. Let's say I have class which represents generic response
public class MyResponse<T> {
private final int httpCode;
private final String message;
private final T data;
}
and resolver for that:
public class ResponseResolver {
public void resolve(Either<AppError, MyResponse<?>> responseToResolve) {
//some logic
}
public void resolveOption(Option<MyResponse<?>> responseToResolve) {
//some logic
}
}
and service where response is resolved with resolver
public class FooService {
private final ResponseResolver responseResolver;
public FooService(ResponseResolver responseResolver) {
this.responseResolver = responseResolver;
}
public void resolveFoo() {
Either<AppError, MyResponse<Foo>> either = Option.of(new MyResponse<>(200, "message", new Foo())).toEither(AppError.ERROR);
responseResolver.resolve(either);
}
public void resolveOptionFoo() {
MyResponse<Foo> foo = new MyResponse<>(200, "message", new Foo());
responseResolver.resolveOption(Option.of(foo));
}
}
I do not understand why resolveOption method which is called in resolveFooOption is a proper way but in method with Either compiler complies that required type is Either<AppError, MyResponse<?> but provided Either<AppError, MyResponse<Foo>. Can anybody explain me why second case is invalid?
I have a utility class OldRemote which has been deprecated now, but still it will be used for a while till the new class NewRemote is stable. And both the utility classes has the same method names and parameters, But the return type pojo classes are different. Even return type pojo structure is same, but naming is different.
In simple, both the function return types are pojo's with different field names.
Is there any generic way to handle this below usecase ?
I have created a service interface which has the generic method contract of both old and new class.
public interface RemoteService {
//contract [ return type is object to receive all/any Pojo classes ]
Object turnOnTV();
static Service GetRemoteservice(boolean isOldRemote){
if(isOldRemote){
return new OldRemote();
}
return new NewRemote();
}
}
OldRemote Class
public class OldRemote implements RemoteService{
#Override
public OldPojo turnOnTV() {
OldPojo oldPojo = new OldPojo();
System.out.println("OldPojo");
return oldPojo;
}
}
NewRemote Class
public class NewRemote implements Service{
#Override
public NewPojo turnOnTV() {
NewPojo newPojo = new NewPojo();
System.out.println("NewPojo");
return newPojo;
}
}
Demo usage of above implementation.
public class DemoTvRemote {
public static void main(String[] args) {
RemoteService remoteService1 = RemoteService.GetRemoteservice(true);
OldPojo oldRemote = (OldPojo) remoteService1.turnOnTV();
RemoteService remoteService2 = RemoteService.GetRemoteservice(false);
NewPojo shr = (NewPojo) Service2.test();
}
}
This above code works fine. But the problem is I don't want to type cast in all the places where turnOnTV() is used in my entire code base. Even If I have to do that, I will have to write a condition to switch between OldPojo and NewPojo where ever the turnOnTV() is invoked.
Is there any way to solve this problem ?
You could create a base class or interface they both extend/implement.
public abstract class RemoteServiceBase<E> {
public abstract E turnOnTv();
}
public class NewRemoteService extends RemoteServiceBase<NewRemotePojo >{
public NewRemotePojo turnOnTv() {
return new NewRemotePojo();
}
}
public class OldRemoteService extends RemoteServiceBase<OldRemotePojo >{
public OldRemotePojo turnOnTv() {
return new OldRemotePojo();
}
}
This would still only work if you know the service type. Otherwise you work with the common generic type as one would expect.
We can deal with this with the following approach :
1) We can create a dummy POJO class in a common location with having the reference of both OldPojo and NewPojo as data members
public class CommonPojo {
OldPojo oldPojo;
NewPojo newPojo;
public void setOldPojo(OldPojo oldPojo){
this.oldPojo=oldPojo;
}
public void setNewPojo(NewPojo newPojo){
this.newPojo=newPojo;
}
public OldPojo getOldPojo(){
return oldPojo;
}
public NewPojo getNewPojo(){
return newPojo;
}
}
2)We can write a Utility method as follow which can give an object of commonpojo :
public class CommonRemote {
public static CommonPojo turnOnTv(Boolean isOldRemote){
CommonPojo commonPojo = new CommonPojo
if(isOldRemote){
OldPojo oldPojo =new OldPojo();
commonPojo.setOldPojo(oldPojo);
}else{
NewPojo newPojo =new NewPojo();
commonPojo.setNewPojo (newPojo);
}
}
}
3) Use this method as turnOnTv() as Follows :
public class DemoTvRemote {
public static void main(String[] args) {
CommonPojo remote1 = CommonRemote.turnOnTv(true);
OldPojo oldRemote = remote1.getOldPojo();
CommonPojo remote2 = CommonRemote.turnOnTv(false);
NewPojo newRemote = remote2.getNewPojo();
}
}
with this approach with little changes in code We can achieve your requirement without any typecasting.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I have a Main class:
public class Retrigger {
public static void main(String[] args){
Long i= 97944605L;
com.armus.flow.Implement rdf = new com.armus.flow.Implement();
try {
rdf.retrfail(i);
}
catch(Throwable e){
System.out.println("In exception a = "+e+" "+i);
e.printStackTrace();
return;
}
}
}
I am calling method retrfail of the Implement class and passing a long value:
import com.armus.common.Dsessionservice;
public class Implement
extends Remote
implements DMSer, Ajaxser {
private Dsessionservice flowservice;
private Dsession getDsession(long sessionId)
throws ServiceException {
try {
dss = this.flowservice.getprocessname(Long.valueOf(sessionId));
}
catch (ServerException e) {
//some code
}
//some code
}
public void retrfail(long sessionId) {
Dsession dss = getDsession(sessionId);
// some code
}
}
The implementing class passes the id to other Dsessionservice interface to get the process name.
public abstract interface Dsessionservice
{
public abstract Dsessionservice getprocessname(Long paramLong)
throws ServerException;
}
The program compiles fine. But I am getting java.lang.nullpointerexception when running the program at the below line
dss = this.flowservice.getprocessname(Long.valueOf(sessionId));
What am I doing wrong here.
Can someone please help?
You forgot to initialize your flowserive variable.
In Java, when you declare a variable like private Dsession flowserive; it is not initialized to anything, and therefore has no member method getprocessname(...) Trying to access this method when it does not exist throws a java.lang.nullpointerexception.
Try something like this :
import com.armus.common.Dsession;
public class Implement
extends Remote
implements DMSer, Ajaxser
{
private Dsession flowserive;
// ADDING CONSTRUCTOR HERE ////
public Implement() {
this.flowservice = new Dsession(); // Or initialize with any parameters you need
}
///////////////////////////////
private Dsession getDsession(long sessionId)
throws ServiceException
{
try
{
dss = this.flowserive.getprocessname(Long.valueOf(sessionId));
}
catch (ServerException e)
{
//some code
}
//some code
public void retrfail(long sessionId)
{
Dsession dss = getDsession(sessionId);
// some code
}
}
I'm sorry I do not know your Dsession class, so maybe you need to change this to initialize the Dsession object correctly...
This question already has answers here:
My program keeps saying that the method cannot be resolved
(2 answers)
Closed 5 years ago.
My class Cupple needs to call the method beStored(char) of a class DataIterator that implements an interface StorableData.
Here the code of this interface StorableData :
package general_classes.cupples;
public interface StorableData {
public void beStored(char c);
}
Here the code of the implementation :
package general_classes.cupples;
public class Cupple<TYPE_OF_ELEMENTS> implements StorableData {
public void beStored(char c) {
}
}
And finally, here the code of the class DataIterator :
package general_classes.DataIteration;
public class DataIterator<StorableData> {
private StorableData root_storable_data;
public List<StorableData> iterate() {
this.root_storable_data.beStored(read_character);
}
}
Please note that I didn't write all the lines.
The problem is that the compiler tells me that he "cannot resolve the method beStored(int).
However, as you can see it, it's actually in the interface. So what's the problem ?
COMPLETE CODE.
INTERFACE :
package general_classes.cupples;
public interface StorableData {
public Cupple beStored(int c);
}
IMPLEMENTATION :
package general_classes.cupples;
import java.util.ArrayList;
public class Cupple<TYPE_OF_ELEMENTS> extends ArrayList<TYPE_OF_ELEMENTS> implements StorableData {
private int position_to_insert_element;
private int number_of_elements;
private Cupple<TYPE_OF_ELEMENTS> next_cupple;
private Cupple<TYPE_OF_ELEMENTS> current_empty_cupple;
public Cupple(int number_of_elements) {
this.position_to_insert_element = 0;
this.number_of_elements = number_of_elements;
}
public Cupple beStored(int c) {
Cupple returned_cupple = this;
if(this.position_to_insert_element > this.number_of_elements) {
this.next_cupple = returned_cupple = new Cupple<>(this.number_of_elements);
} else {
//this.add((TYPE_OF_ELEMENTS) c);
this.position_to_insert_element++;
}
return returned_cupple;
}
public Cupple next() {
return this.next_cupple;
}
}
CLASS :
package general_classes.DataIteration;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* Reads character per character some given data. Stores the character in a
* list, after having casted it in the specified type by the way.
*
* #author e1300478
*
* #param <StorableData>
* the wished type of the reading's returned elements
*/
public class DataIterator<StorableData> {
private Reader reader;
private List<StorableData> returned_elements_list;
private StorableData root_storable_data;
DataIterator(Reader reader, StorableData storable_data) {
this.reader = reader;
this.returned_elements_list = new ArrayList<>();
this.root_storable_data = storable_data;
}
public List<StorableData> iterate() throws IOException {
int read_character;
do {
read_character = this.reader.read();
StorableData storable_data = this.root_storable_data.beStored((int) read_character);
if(!this.returned_elements_list.contains(storable_data)) {
this.returned_elements_list.add(storable_data);
}
} while (read_character > -1);
return this.returned_elements_list;
}
}
The problem is that the compiler tells me that he "cannot resolve the
method beStored(int).
That simply means that you're attempting to pass an int type to the beStored method. If you look at the interface definition of this method again you'll notice that you're not obeying the contract that has been set.
public void beStored(char c);
in the code below read_character is most likely an int type rather than a character hence the error.
this.root_storable_data.beStored(read_character);
Solution
change this:
int read_character;
to this:
char read_character;
also change this:
StorableData storable_data = this.root_storable_data.beStored((int) read_character);
to this:
StorableData storable_data = this.root_storable_data.beStored(read_character);
The problem is this, in DataIterator StorableData is just a generic type, is not the class StorableData, is the same as DataIterator
The following code would compile.
public class DataIterator {
private StorableData root_storable_data;
public List<StorableData> iterate() {
char read_character='x';
this.root_storable_data.beStored(read_character);
return null;
}
}
the title might be not very descriptive but i couldn't think of a better one.
The problem is as follows:
I have one screen (ScreenOne) with a link to another screen (ScreenTwo).
On the ScreenTwo is a link back to ScreenOne.
I implemented this via custom RichTextFields and a custom ChangeListener.
Now the problem is that i keep getting a StackOverflowError!
Is there any way to navigate back and forth in that way?
regards matt
public class MyApp extends UiApplication
{
public static void main(String[] args)
{
MyApp theApp = new MyApp();
theApp.enterEventDispatcher();
}
public MyApp()
{
ScreenOne so = ScreenProvider.getInstance().getScreenOne();
so.initialize();
ScreenProvider.getInstance().getScreenTwo().initialize();
pushScreen(so);
}
}
public class ScreenOne extends MainScreen {
MyTextField link;
public ScreenOne() {
link = new MyTextField("FirstScreen");
add(link);
}
public void initialize(){
link.setChangeListener((FieldChangeListener) new MyFieldChangeListener(ScreenProvider.getInstance().getScreenTwo()));
}
}
public class ScreenTwo extends MainScreen {
MyTextField link;
public ScreenTwo() {
link = new MyTextField("SecondScreen");
add(link);
}
public void initialize(){
link.setChangeListener((FieldChangeListener) new MyFieldChangeListener(ScreenProvider.getInstance().getScreenOne()));
}
}
public class MyFieldChangeListener implements FieldChangeListener {
private Screen nextScreen;
public MyFieldChangeListener(Screen nextScreen) {
this.nextScreen = nextScreen;
}
public void fieldChanged(Field field, int context) {
UiApplication.getUiApplication().pushScreen(nextScreen);
}
}
public class MyTextField extends RichTextField {
public MyTextField() {
super();
}
public MyTextField(String text) {
super(text);
}
protected boolean touchEvent(TouchEvent message) {
if (TouchEvent.CLICK == message.getEvent()) {
FieldChangeListener listener = getChangeListener();
if (null != listener)
listener.fieldChanged(this, 1);
}
return super.touchEvent(message);
}
}
public class ScreenProvider {
private static ScreenProvider instance = null;
private ScreenProvider(){}
public static ScreenProvider getInstance() {
if (instance == null) {
instance = new ScreenProvider();
}
return instance;
}
private ScreenOne screenOne = new ScreenOne();
private ScreenTwo screenTwo = new ScreenTwo();
public ScreenOne getScreenOne() {
return screenOne;
}
public ScreenTwo getScreenTwo() {
return screenTwo;
}
}
The constructor of ScreenOne creates a ScreenTwo instance, and the constructor of ScreenTwo creates a ScreenOne instance. You have an infinite loop here.
Regarding revision 5 of this question:
new ScreenProvider() -> new ScreenOne() -> ScreenProvider.getInstance() -> new ScreenProvider() -> ...
still infinite. Again, the problem is that you're trying to setup a cycle via object constructors. You need to create the objects first, then assign the next and previous.
Regarding revision 4 of this question:
getScreenOne() -> new ScreenOne() -> getScreenTwo() -> new ScreenTwo() -> getScreenOne() -> newScreenOne() -> ...
you still have an infinite loop, because the constructors are trying to store an instance of each other. You need to construct the objects first, then add the cyclic references.
In your ScreenProvider you don't need to make screen1/screen2 static -- they're members of the singleton instance.
Outside of that the other problem I see in this current version is that you're going to be pushing a screen onto the stack -- that's already on the stack. Try popping the prior screen first.
That overflow error is likely the result of an infinite loop caused by constantly jumping from ScreenOne and ScreenTwo. Could you describe what you actually would want to accomplish and/or show a snippet of code?