Duplicate variables (null copy) in loop? - java

I've never seen this before.. I have the following code, a simple nested loop assigning an object from one ArrayList to an object of another.
But, inside the inner loop, the object has some (not all) duplicate variables with null values?!? What am I doing wrong?!?
The first image shows the local variable "member", a reference to an object inside the ArrayList "members". This is the object with duplicate variables with null values.
The second image show the other object "offer", looking like one would expect.
Code below. Help?
public static void setMembersForOffers(ArrayList<WPMemberPost> members, ArrayList<WPOfferPost> offers)
{
int memberCount = members.size();
int offerCount = offers.size();
for (int i=0; i<offerCount; i++)
{
WPOfferPost offer = offers.get(i);
if (offer.memberIdentifier != null)
{
for (int j=0; j<memberCount; j++)
{
WPMemberPost member = members.get(j);
String id = member.identifier; // NULL?!? (Expected "436")
if (offer.memberIdentifier.equalsIgnoreCase(id))
{
offer.member = member;
break;
}
}
}
}
}

Of course two variables with the same name can exist in an inheritance hierarchy
Try this code and make a breakpoint in the main method at System.out.println(subclass);.
In the debugger you will see that the variable exists two times, because it is defined in Base and Subclass.
public class Main {
public static void main(String[] args) {
Subclass subclass = new Subclass();
subclass.someString = "test";
System.out.println(subclass);
}
private static class Base {
public String someString;
}
private static class Subclass extends Base {
public String someString;
}
}

Related

Java Inheritance: How to override instance variables/fields from parent class?

Update: I can change the variables from being private, static, or final.
I have a parent class and a child class. I want to re-use a method in the parent class. Normally, this is as easy as super.methodFromParentClass() and you're done. However, when I do this, the method I want to re-use is using instance variable data from the Parent class, which is wrong or rather, I do not want this behavior. I have DIFFERENT initialized data in the child class that needs to get passed into the method I want to reuse. If you look at the method I want to re-use (below is just an example to make it simple, but the idea is the same), I am creating multiple objects in there that use the instance variables of the class its called in. So you can see why when I call super.methodIWantToReuse it won't work, because it will take the Parent data and pass it into the objects, even though I really want it to pass the data I initialize in the child class. My real example is also creating way more objects and I have way more instance variables, so I really want to re-use this code (DRY principle) if at all possible.
How can I get around this? Would using getters i.e. getFirstName() and overriding them in the Child class, thus using Runtime Polymorphism when I call super.methodIWantToReuse(), would grab/use the Child class instance variable data be the only way???
public class ParentClass {
private static final String firstName = "Billy Ray";
private static final String lastName = "Cyrus";
private static final int age = 58;
private static final String city = "Hunstville";
public boolean methodIWantToReuse() {
Object1 obj1 = new Object(firstName, lastName);
Object2 obj2 = new Object(age,city);
Object3 obj3 = new Object(obj1, obj2);
Object4 obj4 = new Object(obj3);
// Passing in the objects created above as argument, which have the Parent instance variable data
return someRandomMethodHere(obj4);
}
public class ChildClass {
private static final String firstName = "Miley";
private static final String lastName = "Cyrus";
private static final int age = 27;
private static final String city = "Los Angeles";
public boolean methodIWantToReuse() {
// DOESN'T WORK CORRECTLY, because ends up using the instance variable data of PARENT class, but it
// needs to use CHILD class instance variable data
super.methodIWantToReuse();
}
Your parent class instance variables are Private to that, so you can't update them from Child class. So rather you use parameterize method or create Protected setter/getter for instance variables (or protected variable itself). In you your case the variables are final so you actually can't even update them. So technically that's not possible to use child class variables in parent class.
If you update your variable to protected and remove static/final modifiers (as you mentioned in comments that you can). Before calling method from parent class, update variable data before calling super method. You can do it as below:
Approach 1 : Updating data in parent class before calling parent class method.
Parent Class:
public class ParentClass {
protected String firstName = "Billy Ray";
protected String lastName = "Cyrus";
protected int age = 58;
protected String city = "Hunstville";
public boolean methodIWantToReuse() {
// Passing in the objects created above as argument, which have the Parent
// instance variable data
Object1 obj1 = new Object(firstName, lastName);
Object2 obj2 = new Object(age,city);
Object3 obj3 = new Object(obj1, obj2);
Object4 obj4 = new Object(obj3);
return someRandomMethodHere(obj4);;
}
}
Child Class:
public class ChildClass extends ParentClass {
protected String firstName = "Miley";
protected String lastName = "Cyrus";
protected int age = 27;
protected String city = "Los Angeles";
public boolean methodIWantToReuse() {
// Update data in Parent class first
super.firstName = firstName;
super.lastName = lastName;
super.age = age;
super.city = city;
return super.methodIWantToReuse();
}
}
Approach 2 : If you want to use parameterized method to make it stateless, you can do it as below:
Parent Class:
public class ParentClass {
protected String firstName = "Billy Ray";
protected String lastName = "Cyrus";
protected int age = 58;
protected String city = "Hunstville";
public boolean methodIWantToReuse() {
return methodIWantToReuse(this.firstName, this.lastName, this.age, this.city);
}
public boolean methodIWantToReuse(String firstName, String lastName, int age, String city) {
// Passing in the objects created above as argument, which have the Parent
// instance variable data
Object1 obj1 = new Object(firstName, lastName);
Object2 obj2 = new Object(age,city);
Object3 obj3 = new Object(obj1, obj2);
Object4 obj4 = new Object(obj3);
return someRandomMethodHere(obj4);;
}
}
Child Class:
public class ChildClass extends ParentClass {
protected String firstName = "Miley";
protected String lastName = "Cyrus";
protected int age = 27;
protected String city = "Los Angeles";
public boolean methodIWantToReuse() {
// Update data in Parent class first
return super.methodIWantToReuse(this.firstName, this.lastName, this.age, this.city);
}
}
NOTE: It's not good practice to keep local variables name same as the class level variables. But kept it here same for just understanding.
You can not override fields of a class. Only methods can be overridden. In your case you have to use getters and override them in sub class.
In case you really mean instance variables instead of your static variables (or class variables) as shown in your example, you could make them accessible for your subclass by changing the access modifier and removing the final keyword.
If, however, you actually mean static variables, you cannot reassign them in each subclass as they would all share the same static variables defined by the ParentClass, meaning the last loaded class would be the only result you get by calling your ParentClass#methodIWantToReuse.
Best would be to use OOP to your advantage by instantiating new individual objects with the required arguments, and using them.
By this I mean instead of doing this:
public class Example {
public static class ParentClass {
protected String name;
protected int age;
public ParentClass() {
name = "The parent";
age = 35;
}
public String methodIWantToReuse() {
return name + " is " + age + " years old.";
}
}
public static class AChildClass extends ParentClass {
public AChildClass() {
name = "Alice";
age = 13;
}
}
public static class AnotherChildClass extends ParentClass {
public AnotherChildClass() {
name = "Bob";
age = 21;
}
}
public static void main(String[] args) {
// Prints "The parent is 35 years old."
System.out.println(new ParentClass().methodIWantToReuse());
// Prints "Alice is 13 years old."
System.out.println(new AChildClass().methodIWantToReuse());
// Prints "Bob is 21 years old."
System.out.println(new AnotherChildClass().methodIWantToReuse());
}
}
Do this:
public class Example {
public static class ParentClass {
protected String name;
protected int age;
// Variables instantiated here to not cause confusion
public ParentClass() {
name = "The parent";
age = 35;
}
public String methodIWantToReuse() {
return name + " is " + age + " years old.";
}
}
public static class ChildClass extends ParentClass {
public ChildClass(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
// Prints "The parent is 35 years old."
System.out.println(new ParentClass().methodIWantToReuse());
// Prints "Alice is 13 years old."
System.out.println(new ChildClass("Alice", 13).methodIWantToReuse());
// Prints "Bob is 21 years old."
System.out.println(new ChildClass("Bob", 21).methodIWantToReuse());
}
}
This should also be along the lines of the DRY principle, as you want to reuse your code as efficient as possible instead of coding technically the same over and over again.
As you can see, there was no need for me to override ParentClass#methodIWantToReuse or call the ChildClass' super's implementation.

Java - defining unknown number of variables in an entity

I need an entity called DynamicEntity for example, in which I must define an UNKNOWN number of variables with theyr setters and getters. The variables must have a name I want to give them, so for this i got:
The main class:
public class Main {
public static void main(String[] args) {
DynamicEntity dynamic = new DynamicEntity();
dynamic.parseVariable("int");
}
}
And the DynamicEntity class:
public class DynamicEntity {
public void parseVariable(String text) {
String[] tokens = text.split("-");
String variableType = tokens[0];
String variableName = tokens[1];
if (variableType.equals("int")) {
int variableName = 0;
}
}
}
Definetly the variableName will not be accepted due to its defined already.
The thing is that i dont want the variable inside the IF to be called variableName, I want the variable to be called as the whats inside the tokens[1].
And of course creating setters and getters for every new variable added, which i have no clue what to do for this.
You can benefit from the Map structure. Where as the key you put the name of your member and as value the value for it.
A simple example of concept:
class Dynamic {
private final Map<String,Object> members = new HashMap<>();
public void setMember(String name, Object value) {
members.put(name,value);
}
public Object getMember(String name) {
return members.get(name);
}
}

Array only outputs last array initialized

I am having an issue with declaring and initializing object arrays within Java using jGrasp. This is an assignment and I copied the code straight from the book and changed the class and array name. I have tried assigning and initializing without an array by using 'itemA, itemB, itemC' with the same duplicate output as you can see at the bottom of the code.
Driver class:
class Driver
{
public static void main(String[] args)
{
RetailItem[] item = new RetailItem[3];
item[0] = new RetailItem("a", 1, 1);
item[1] = new RetailItem("b", 2, 2);
item[2] = new RetailItem("c", 3, 3);
for (int i = 0; i < item.length; i++)
{
System.out.printf("item: " + item[i].getItemName());
}
}
The output results in:
item: c
item: c
item: c
I do not understand as I am a beginner as to why the output is always the last array object initialized.
The output that I am attempting is:
item: a
item: b
item: c
Here is my RetailItem class:
class RetailItem
{
private static String itemName;
private static int unitsOnHand;
private static double priceEach;
//Constructor(s)
public RetailItem(String name, int qty, double price)
{
itemName = name;
unitsOnHand = qty;
priceEach = price;
}
//Public Methods
public static double getPriceEach()
{
return priceEach;
}
public static String getItemName()
{
return itemName;
}
public static int getUnitsOnHand()
{
return unitsOnHand;
}
}
Your problem is that itemName (and all your other variables) have been declared static. This binds them to the class, not to an instance, so when your constructor alters itemName, it alters that variable for the whole class.
To see what I mean by "class variable", try this: define a main method in RetailItem that looks like this:
public static void main(String[] args) {
// Print the property of the RetailItem *class*: remember, you don't even have an instance of the class at this point.
System.out.println(RetailItem.itemName); // null
RetailItem item = new RetailItem("a", 1, 1);
// Print the property of the class again, ignoring the instance that you created.
System.out.println(RetailItem.itemName); // "a"
}
To resolve this, just remove the static declaration from anything you intend to be an instance variable (as well as the setters/getters!).
private String itemName;
public String getItemName() {
return itemName;
}
The problem is that you're setting the itemName, unitsOnHand, and priceEach as static. Basically this means that all instances of RetailItem will have the same value for each of those variables. If you remove the static keyword each instance will have their own itemName, unisOnHand, and priceEach variables.

Changing parent object to child object

I need a bit of help here. so i have this. I was basically wondering when you create an array of object of a parent class, then change that object to a child class, can I access the methods of that child class and if not why. thanks for any help.
public class Racer {
private String name;
private int position;
// Constructor
public Racer()
{}
public Racer(String name)
{
this.name = name;
position = 0;
}
public String getName()
{
return name;
}
public int getPosition()
{
return position;
}
public void setPosition(int n)
{
position = n;
}
public void setName(String n){
this.name=n;
}
}
the child class
public class Spartiates extends Racer{
private int energy;
public Spartiates(){
super();
}
public Spartiates(String name){
setName(name);
setPosition(20);
energy=100;
}
public void setEnergy(int energy){
this.energy=energy;
}
public int getEnergy(){
return energy;
}
}
main class
public class demo{
public static void main(String[] args){
Racer [] player = new player[3];
for(int i=0; i<player.length; i++){
player[i] = new Spartiates();
}
System.out.println(player[1].getEnergy());
}
so here the problem the getEnergy method doesn't work so I was wondering why. If anybody can help it would be very much appreciated. thanks
This is discussed here:
Is it possible to call subclasses' methods on a superclass object?
Along with all the reasons why doing something like this is probably never a good idea :).
You'll have to cast it to an instance of the subclass. If you plan on having a mixed array of object instances you'd need to first check the type:
System.out.println(((Racer)player[1]).getEnergy());
You need either define the function in the superclass or cast the object to the subclass.
If you intend the array to hold ONLY elements of the subclass Spartiates, then declare it as such.
Otherwise, if it needs to hold objects of both type, there only way to do this is to check with instanceof.
if (player[1] instanceof Spartiates)
System.out.println(((Spartiates)player[1]).getEnergy());
else
// handle other types
The reason energy is 0 is because you are calling your empty (no arg) constructor:
player[i] = new Spartiates();
which does not initialize the energy variable (so it will be 0 by default). You only set the variable to 100 in the constructor which takes in a String, namely here:
public Spartiates(String name){
setName(name);
setPosition(20);
energy=100;
}
So either call that constructor in the for loop with some string as an argument, or call your setEnergy() setter with some value after creating the object with the empty constructor.
Also, this is wrong:
Racer [] player = new player[3];
It should read:
Racer [] player = new Racer[3];
or:
Racer [] player = new Spartiates[3];

Java: Problems with "this" keyword [duplicate]

This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 9 years ago.
I am trying to make a Java package 'mylib' with classes Library{} and Book{}.
Here is the code for class Library{}:
/*
Create collection of books
List books and status
User input:
'B' - Borrow a book
'R' - Reserve a book
'I' - Return a book
'X' - Exit program
*/
package mylib;
public class Library {
public static void main(String[] args) {
Book[] MyBooks = new Book[3];
Book x;
MyBooks[0] = new Book("The Lover's Dictionary", "Levithan, D.", 211);
MyBooks[1] = new Book("White Tiger", "Adiga, A.", 304);
MyBooks[2] = new Book("Thirteen R3asons Why", "Asher, J.", 336);
for (int i = 0; i < MyBooks.length; i++) {
x = MyBooks[i];
System.out.println((i + 1) + " " + x.sTitle);
}
}
}
Here is the code for class Book{}:
package mylib;
class Book {
// Declare fields
byte iStatus;
int iPages;
String sTitle, sAuthor;
String sBorrowedBy, sReservedBy;
String sDueDate, sReturnDate;
public static final byte BORROWED = 0, AVAILABLE = 1, RESERVED = 2;
// Constructor
public Book(String Title, String Author, int Pages) {
this.sTitle = Title;
this.sAuthor = Author;
this.iPages = Pages;
this.iStatus = this.AVAILABLE;
}
// Borrow method
static void borrowBook(String Borrower, String Due) {
if (this.iStatus == this.AVAILABLE) {
this.sBorrowedBy = Borrower;
this.sDueDate = Due;
this.iStatus = this.BORROWED;
} else if (this.iStatus == this.RESERVED
&& this.sReservedBy == Borrower) {
this.sBorrowedBy = Borrower;
this.sDueDate = Due;
this.sReservedBy = "";
this.iStatus = this.BORROWED;
}
}
/*
* static int reserveBook(String Borrower) {
*
* }
*
* static void returnBook(String Return) {
*
* }
*/
}
The partial codes above are given by the professor. I commented out the empty methods and tested the program just to see if it would compile.
I am having 14 errors with the this keyword. Any help?
in this method
static void borrowBook(String Borrower, String Due) {
You cannot use this in a static context
As I see ,there is no need of making that method static.
Prefer to read Understanding Instance and Class Members
You cannot use this in static context , like static methods. Why are you making your borrowBook() method as static. It should be an instance method without the static keyword.
static methods belong to the class and is shared by all its instances. You can invoke them directly using the classname like Book.borrowBook(....) , if this happens the run time will have no idea what/which object this refers to in that context .
Read JLS.3 15.8
The keyword this may be used only in the body of an instance method, instance initializer, or constructor, or in the initializer of an instance variable of a class. If it appears anywhere else, a compile-time error occurs.
In your case better to make the borrowBook() method an instance method as it changes the state of the invoking object i.e. modifies its attributes.Just change the method declaration and remove static:
void borrowBook(String Borrower, String Due) {....... }
Since you are using this in a static context it is giving you the error. Try the following code:
package myLib;
class Book {
// Declare fields
byte iStatus;
int iPages;
String sTitle, sAuthor;
String sBorrowedBy, sReservedBy;
String sDueDate, sReturnDate;
public static final byte BORROWED = 0, AVAILABLE = 1, RESERVED = 2;
// Constructor
public Book(String Title, String Author, int Pages) {
this.sTitle = Title;
this.sAuthor = Author;
this.iPages = Pages;
this.iStatus = Book.AVAILABLE;
}
// Borrow method
//Remove the static keyword
//Refer to the remaining static variables like AVAILABLE OR BORROWED using Book and not this keyword.
void borrowBook(String Borrower, String Due) {
if(this.iStatus == Book.AVAILABLE) {
this.sBorrowedBy = Borrower;
this.sDueDate = Due;
this.iStatus = Book.BORROWED;
}
else if(this.iStatus == Book.RESERVED && this.sReservedBy == Borrower) {
this.sBorrowedBy = Borrower;
this.sDueDate = Due;
this.sReservedBy = "";
this.iStatus = Book.BORROWED;
}
}
}
I suggest you to use IDE to coding since this issue will understand by your own. because error is here use this in a static block.
this keyword is used to refer non-static variables from non-static methods. You are referring to non-static variables from static method.
just change this line :
static void borrowBook(String Borrower, String Due) {
to
public void borrowBook(String Borrower, String Due) {

Categories

Resources