object array assignment problem - java

I have a problem where each element of my array seem to be reassigned.
class Car {
private static int nom = 0;
private static String whee = "";
public void setCar(int r, String s) {
this.nom = r;
this.whee = s;
}
}
class Rawr {
private Car[] jar = new Car[3];
public Mar() {
jar[0] = new Car();
jar[1] = new Car();
jar[2] = new Car();
jar[0].setCar(2, "yar");
jar[1].setCar(3, "tar");
jar[2].setCar(4, "sars");
}
}
If I printed it like jar[0].nom + jar[0].whee + jar[1].nom + jar[2].whee + jar[3].whee, the output would be
4 sars 4 sars sars

It's because your variables are static i.e. they belong to the class, rather than to an instance. Take a look at Java Tutorials | Understanding Instance and Class Members for more information about what this means.
You should remove the static keyword, so that they become instance variables.

Change
private static int nom = 0;
private static String whee = "";
to
private int nom = 0;
private String whee = "";
static means the variable is shared by all instances. (The fact you can use this to refer to static variables is a Java oddity.)

Your nom and whee fields are static. This means that they are tied to the class, and not to the object (instance) of the class.
Thus, when you assign a new value to this.nom, in reality, you assign a the value to Car.nom. The compiler allows referring to static variables through an object, but it's very bad practice. You should always refer to static fields by their class : Car.nom, Car.whee. This makes it clear that the nom and whee are static, and thus shared by all instances of the class. In this case, these fields should not be static : each Car instance has its own name and whee (whatever it might be).

A better way to structure your code is as follows.
class Car {
private final int nom;
private final String whee;
public Car(int nom, String whee) {
this.nom = nom;
this.whee = whee;
}
public String toString() { return num + " " + whee; }
}
class Rawr {
private final Car[] jar = {new Car(2, "yar"), new Car(3, "tar"), new Car(4, "sars")};
public String toString() {
return Arrays.toString(jar);
}
}

Related

Why is my JTextField not saving the input properly? [duplicate]

I am currently working on a small Java application and I ran into a problem. I create two different variables, but after I run the code, the first variable is getting the same value as the second one. They should be different.
Here is my custom file class:
public class MyFile {
private static String path;
private static String name;
private static final String FILE_SEPARATOR = "/";
public MyFile(String path) {
System.out.println(path);
this.path = "";
this.name = "";
this.path = /*FILE_SEPARATOR*/path;
String[] dirs = path.split(FILE_SEPARATOR);
this.name = dirs[dirs.length - 1];
}
public static String getPath() {
return path;
}
public static String getName() {
return name;
}
public String toString() {
return "Path: " + path + ", Name: " + name;
}
}
Here I am using the variables:
MyFile modelFile = new MyFile("res\\model.dae");
MyFile textureFile = new MyFile("res\\diffuse.png");
System.out.println(modelFile.toString());
System.out.println(textureFile.toString());
The output is the following: http://imgur.com/a/Nu3N6
In MyFile class, you declare these fields as static fields :
private static String path;
private static String name;
So you can assign to them a single value as a static field is shared among all instances of the class.
You should rather declare these fields as instance fields to have distinct values for each MyFile instance :
private String path;
private String name;
First you want to know about static keyword:
Attributes and methods(member of a class) can be defined as static.
static members do not belongs to an individual object.
static members are common to all the instances(objects of the same class).
static members are stores in static memory(a common memory location which can by everybody).
Becauseof two member variables are static. Each objects share the values of these two variables(values are common for every objects).
private static String path;
private static String name;
Remove the static in both variables. Then each and every object will hold a individual values for these variables.
When Defining an Entity class the class variable show be private period. Unless you want to access these variable statically, as in without having to instantiate the class or using getters and setter. If you use getters and setters as you have done above, and clearly made an instance of the class you want use ensure you don't use static access modifiers for the class variables.
The modified code is-as below.
package StackOverflowProblemSets;
/**
* Created by HACKER on 05/06/2017.
* Two different variables getting same value
*/
public class MyFile {
private String path;
private String name;
private static final String FILE_SEPARATOR = "/";
public MyFile(String path) {
System.out.println(path);
this.path = "";
this.name = "";
this.path = /*FILE_SEPARATOR*/path;
String[] dirs = path.split(FILE_SEPARATOR);
this.name = dirs[dirs.length - 1];
}
public String getPath() {
return path;
}
public String getName() {
return name;
}
public String toString() {
return "Path: " + path + ", Name: " + name;
}
public static void main(String[] args) {
MyFile modelFile = new MyFile("res\\model.dae");
MyFile textureFile = new MyFile("res\\diffuse.png");
System.out.println(modelFile.toString());
System.out.println(textureFile.toString());
}
}
You need to know about static and local variables.
Static variables of a class are such variables which are common to all instances of that class and are shared by all of the instances. E.g. if I have a class:
public static class myClass{
public static int staticVar;
//Constructor
public myClass(){
staticVar = 0;
}
}
and then I have the following code in a main method of another class:
public static void main(String args[]){
myClass c1, c2;
c1 = new myClass();
c2 = new myClass();
c1.staticVar = 4;
c2.staticVar = 8;
System.out.println(c1.staticVar + " " + c2.staticVar);
}
then my output will be:
8 8
This is because the variable staticVar is shared by both c1 and c2. First when the statement c1.staticVar = 4 is executed, the value of staticVar for both c1 and c2 is 4. Then the statement c2.staticVar = 8 is executed to change the value of staticVar of both classes to 8.
So in your problem, you have to make your name and path variables non-static to give each of your myFile instances a different value of the variables.
I hope this helps.
You problem is second file path is overlap of first file path. So, check this code:
MyFile modelFile = new MyFile("res\\model.dae");
MyFile textureFile = new MyFile("res\\diffuse.png");
System.out.println(new MyFile("res\\model.dae"));
System.out.println(new MyFile("res\\diffuse.png"));

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.

Update a single variable of a class in an ArrayList of class in java

I have a class Components:
public class Components {
int numberOfNets;
String nameOfComp;
String nameOfCompPart;
int numOfPin;
public components(int i, String compName, String partName, int pin) {
this.numberOfNets = i;
this.nameOfComp = compName;
this.nameOfCompPart = partName;
this.numOfPin = pin;
}
}
Inside another class I created an arraylist of Components class:
List<Components> compList = new ArrayList<Components>();
Later in the code, I am adding the elements in List in this way:
compList.add(new Components(0,compName,partName,0));
See, here numberOfNets and numOfPin variables in Components class are initiated with 0 values. But these values are getting calculated/incremented in a later part of code and hence I need to update the new values of only these two variables in each list element. Now from ArrayList doc I get the idea of updating a list element using its index by set operation. But I am confused how to set/update a particular variable of a class in an ArrayList of a class. I need to update only these two mentioned variables, not all of the four variables in Components class. Is there any way to do that?
You should add getter/setter to your component class so that outer class can update component's members
public class Components {
private int numberOfNets;
private String nameOfComp;
private String nameOfCompPart;
private int numOfPin;
public components(int i, String compName, String partName, int pin) {
setNumberOfNets(i);
setNameOfComp(compName);
setNameOfCompPart(partName);
setNumOfPin(pin);
}
public void setNumberOfNets(int numberOfNets) {
this.numberOfNets = numberOfNets;
}
// Similarly other getter and setters
}
You can now modify any data by using following code because get() will return reference to original object so modifying this object will update in ArrayList
compList.get(0).setNumberOfNets(newNumberOfNets);
Example code.
public class Main {
public static void main(String[] args) {
List<Components> compList = new ArrayList<Components>();
compList.add(new Components(0, "compName", "partName", 0));
System.out.println(compList.get(0).toString());
compList.get(0).numberOfNets = 3;
compList.get(0).numOfPin = 3;
System.out.println(compList.get(0).toString());
}
}
Your class.
public class Components {
int numberOfNets;
String nameOfComp;
String nameOfCompPart;
int numOfPin;
public Components(int i, String compName, String partName, int pin) {
this.numberOfNets = i;
this.nameOfComp = compName;
this.nameOfCompPart = partName;
this.numOfPin = pin;
}
public String toString() {
return this.numberOfNets + " " + nameOfComp + " " + nameOfCompPart
+ " " + numOfPin;
}
}
The output:
0 compName partName 0
3 compName partName 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) {

How to increment a field member in a java class each time a new one is instantiated

VERY new to Java, so I am feeling like a child right now. The joys of learning a new language I guess.
Here is my Invoice Class:
public class Invoice {
//member inits
private int numberOfInvoices = 0;
private String companyName;
private double amountDue;
private String chargeDate;
private static int invoiceNumber = 0;
//constructor
public Invoice(String _companyName, double _amountDue, String _chargeDate)
{
numberOfInvoices++;
companyName = _companyName;
amountDue = _amountDue;
chargeDate = _chargeDate;
invoiceNumber = numberOfInvoices;
}
//getters
public String getCompanyName()
{
return companyName;
}
public double getAmountDue()
{
return amountDue;
}
public String getChargeDate()
{
return chargeDate;
}
public int getInvoiceNumber()
{
invoiceNumber = numberOfInvoices + 1;
return invoiceNumber;
}
//setters
public void setCompanyName(String _companyName)
{
companyName = _companyName;
}
public void setAmountDue(double _amountDue)
{
amountDue = _amountDue;
}
public void setChargeDate(String _chargeDate)
{
chargeDate = _chargeDate;
}
//helpers
public int incrementInvoices()
{
return numberOfInvoices++;
}
}
And here is the main method where I am trying to create three of these invoices, but increment the invoice number each time a new one is created.
public class InvoiceCreator {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Invoice invoice1 = new Invoice("Amazing Software", 5000.00, "January 18, 2009");
System.out.println(invoice1);
Invoice invoice2 = new Invoice("Best Programs", 4000.00, "February 18, 2009");
System.out.println(invoice2);
Invoice invoice3 = new Invoice("Champion Code", 3000.00, "March 18, 2009");
System.out.println(invoice3);
}
}
I'm also new to the IDE (netbeans), but through debugging and looking at each of the classes I created, all the fields are being initialized correctly, but the invoiceNumber = 1 on every one of them.
What am I doing incorrectly here?
You need to use a static field to generate incremental invoice numbers, not store the individual invoice numbers.
Try this:
public class Invoice {
//member inits
private static int nextInvoiceNumber = 0;
private String companyName;
private double amountDue;
private String chargeDate;
private int invoiceNumber = 0;
//constructor
public Invoice(String _companyName, double _amountDue, String _chargeDate)
{
invoiceNumber = nextInvoiceNumber;
nextInvoiceNumber++;
companyName = _companyName;
amountDue = _amountDue;
chargeDate = _chargeDate;
}
....
Declare numberOfInvoices to be static, so that there is a single value for the entire class, rather than a separate value for each instance.
private static int numberOfInvoices = 0;
You declared invoiceNumber as static, but numberOfInvoices is not static. In your constructor you are incrementing the number of invoices - which, being non-static, is initialised to 0 every time you create an instance of it. Then you assign this value to your invoice number.
The simple fix for your case is to declare the numberOfInvoices as static and invoiceNumber as non static:
private static int numberOfInvoices = 0;
private int invoiceNumber;
then you'll get the desired behaviour.
At the same time, it's worth noting that this implementation is ok for the purpose of learning the language, however it will not work for a production system, because the number will still be reset to 0 when the application exits and is restarted. In a production system, you would want to keep this number in a database or external file somewhere. You would then need to ensure that it's incremented in a thread-safe manner. In a production system, your logic would be something like this:
private int invoiceNumber;
private Object sync;
public Invoice(...) {
synchronised(sync) {
invoiceNumber = loadLastInvoiceNumberFromStorage();
invoiceNumber++;
writeLastInvoiceNumberFromStorage(invoiceNumber);
}
...
}
numberOfInvoices should be static. invoiceNumber should not be static. And you should synchronize the access to this field. See also: What is the best way to increase number of locks?
numberOfInvoices isn't the static member.
You currently increment an instance property and set it to the static property.
I suspect you want the opposite.
You could use a static field numberOfInvoices in your class, and increment it in the constructor.
Then you could have a static getter for the field.
numberOfInvoices will always be 0 when a new object is created. So, everytime you increment it and assign it to invoiceNumber, invoiceNumber gets the value 1. Instead, why dont you directly increment invoiceNumber .
use
private static int numberOfInvoices = 0;
Reason:
Static variables are related to class while nonstatic variables are related to object. As in this case you are storing the count of the object of the class so this is related to class. Thus you have to store it as static variable ( also called class variable)
For more details see here
You should declare your numberOfInvoices member as a static member :
private static int numberOfInvoices = 0;
This way all Invoice instance will share this member. If you don't declare it each Invoice instance will have their own value.

Categories

Resources