This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I'm trying to get the length of seznam2 by using int postle in Stanovanje. However, the variable getPostle() does not pass and I get Exception in thread "main" java.lang.NullPointerException error for this line:
private String[] seznam2 = new String[getStanovanje().getPostle()].
I would also like to know when to use:
Stanovanje stanovanje = new Stanovanje();
or
private Stanovanje stanovanje1;
Here is my code:
Potovanje.java
public class Potovanje {
Stanovanje stanovanje = new Stanovanje();
private Stanovanje stanovanje1;
private String datumOdhoda;
private int trajanje;
private Popotnik[] popotnik;
private ArrayList<Popotnik> seznam = new ArrayList<>();
private String[] seznam2 = new String[getStanovanje().getPostle()];
public Potovanje(String datumOdhoda, int trajanje){
this.datumOdhoda = datumOdhoda;
this.trajanje = trajanje;
}
public void setStanovanje(Stanovanje stanovanje1){
this.stanovanje1 = stanovanje1;
}
public Stanovanje getStanovanje(){
return stanovanje1;
}
public void setPopotnik(Popotnik[] popotnik){
this.popotnik = popotnik;
}
public Popotnik[] getPopotnik(){
return popotnik;
}
public ArrayList<Popotnik> getSeznam(){
return seznam;
}
public void setSeznam2(String[] seznam2){
this.seznam2 = seznam2;
}
public String[] getSeznam2(){
return seznam2;
}
public void dodajPotnika(Popotnik[] popotnik){
//System.out.println("postle: " + stanovanje.getPostle());
for(int i=0; i<getSeznam2().length; i++){
//System.out.println("wadap");
setPopotnik(popotnik);
seznam.add(getPopotnik()[i]);
}
}
public String toString(){
return "datumOdhoda: " + datumOdhoda + "\n" + "trajanje: " + trajanje + "\n" + "popotnik: " + getPopotnik();
}
}
Stanovanje.java
public class Stanovanje {
private int postle;
public Stanovanje(){
}
public Stanovanje(int postle){
this.postle = postle;
}
public void setPostle(int postle){
this.postle = postle;
}
public int getPostle(){
return postle;
}
public String toString(){
return "postle: " + postle;
}
}
The difference between 1 and 2:
/*1*/ Stanovanje stanovanje = new Stanovanje();
/*2*/ private Stanovanje stanovanje1;
is:
1 : has the default visibility (which is "package-private") and is immediately initialized. ( not null)
2 : has private visibility and is not initialized ( thus == null until otherwise initialized )
When to use each of those is hard to answer because there maybe a lot of cases where you'd prefer the one or the other.
If you use the second, you should initialize it in the constructor. Either by creating an instance there or by initialize it to a CTOR-Argument. Otherwise your object is not properly initialized and usage can lead to what you encountered: side-effects like an NPE.
In some cases (heavy objects that are rarely actually needed) it can be useful to leave them uninitialized until really needed (sometimes referred to as "lazy loading"). One would then use a getter that checks if the field has been initialized and do so if not before returning it.
About visibility you can read here: Controlling Access to Members of a Class (Oracle Documentation)
Oracles "rule of thumb" there:
Use private unless you have a good reason not to.
Related
This question already has answers here:
Declare final variable, but set later
(7 answers)
Closed 5 years ago.
How can I make sure that the value of String variable doesnot change after being assigned once? Assignment is not at the time of declaration.
More clarity :-
String x = y; (y is another string)
Even if y changes x should not change. How to make sure this?
What I have tried :-
Created a custom class:-
public class MyDs {
private final String unitName;
public MyDs(String iUnitName){
unitName = iUnitName;
}
public String getUnitName(){
return unitName;
}
}
in the main method :-
String iName = "xyz";
MyDs MyDsObj = new MyDs(iName);
But even after this, the value changes when the variable changes.
How can I solve this issue?
Your class be should be design as mentioned in below code
public class TestingClas {
private String name;
public void setName(String name) {
if (this.name == null && name != null)
this.name = name;
}
public String getName() {
return name;
}
}
Now use below code for testing purpose
TestingClas testingClas = new TestingClas();
testingClas.setName("Abdul Waheed");
testingClas.setName("You cannot change me any more now");
String updatedString = testingClas.getName();
updatedString variable will be having old value
as far as I understand ,you should design your class in a way that your variable should be final . with this approach you set it in constructor and then nothing can make it changes. even the referance it is holding is changed the value remains the same I mean a new object is created in heap and value of your final variable is kept same. below is a kind of design which makes the variable x set once and never be able to changed afterwards. Of course this is in instance scope, for class scope you can make your class singelton etc.
public class Test {
private final String x;
private String y;
public Test(String x){
this.x=x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
public String getX() {
return x;
}
}
Change your MyDs class to a singleton class
Making this a singleton class ensures that the final String unitName is updated only once and then it will cannot be altered again.
public class MyDs {
private final String unitName;
private static MyDs myDs;
public static MyDs getMyDsObject(String iUnitName) {
if (myDs == null) {
myDs = new MyDs(iUnitName);
}
return myDs;
}
private MyDs(String iUnitName) {
unitName = iUnitName;
}
public String getUnitName() {
return unitName;
}
}
Here the values "xyz" is stored in unitName and doesnot get updated again when you change to "zxy".
MyDs MyDsObj = MyDs.getMyDsObject("xyz");
Log.i("value", "" + MyDsObj.getUnitName());
MyDs MyDsObj1 = MyDs.getMyDsObject("zxy");
Log.i("value",""+MyDsObj.getUnitName());
Well, you question is not really clear (and the comment section is really chaty...), but if you want to only be able to set a value once but not during the initialisation, setters are not a bad choice. Just add a constraint.
public class MyClass{
private static final String DEFAULT_VALUE = new String("");
private String value = DEFAULT_VALUE;
public final void setValue(String value){
if(this.value != DEFAULT_VALUE) //use the reference on purpose
throw new IllegalArgumentException("This value can't be changed anymore");
this.value = value;
}
// Don't return `DEFAULT_VALUE` to prevent someone to gain access to that instance
public final String getValue(){
return this.value == DEFAULT_VALUE ? null : this.value;
}
}
This will be done at runtime, but this would do the trick.
Now, this is an immutable instance, with some mutable instance you might want to do a copy of it to be sure it can't be modifier using the original reference.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
getting a frustrating null exception error when the class junction is being used in functions. The class should be initialised so this shouldn't be an issue. Help ;_;
class RobotData {
class Junction {
public int juncX;
public int juncY;
public int arrivalHeading;
}
private static int maxJunctions = 10000; //Max junctions likely to occur
private static int junctionCounter;
private static Junction[] junction;
RobotData() {
junctionCounter = 0;
junction = new Junction[maxJunctions];
}
public void resetJunctionCounter() { junctionCounter = 0; }
public void recordJunction(IRobot robot) {
junction[junctionCounter].juncX = robot.getLocation().x;
junction[junctionCounter].juncY = robot.getLocation().y;
junction[junctionCounter].arrivalHeading = robot.getHeading();
junctionCounter++;
}
public void printJunction() {
System.out.println(junction[junctionCounter].juncX);
System.out.println(junction[junctionCounter].juncY);
System.out.println(junction[junctionCounter].arrivalHeading);
}
}
The class RobotData is being initialised properly, but when the functions are being called I get the null error indicating that junction[junctionCounter] hasn't been initialised yet. Unsure why (obviously) as it should be initialised when RobotData is.
When you write this line:
junction = new Junction[maxJunctions];
You create an array of maxJunctions references to Junction instances on the heap. All of them are null until you point them to an object on the heap by calling new.
Here's another idea:
public class Junction {
public final int juncX;
public final int juncY;
public final int arrivalHeading;
public String toString() {
return String.format("x = %d y = %d arrivalHeader = %d", juncX, juncY, arrivalHeading);
}
}
public class RobotData {
private List<Junction> junctions;
RobotData() {
this.junctions = new ArrayList<Junction>();
}
public void recordJunction(IRobot robot) {
Junction junction = new Junction();
junction.juncX = robot.getLocation().x;
junction.juncY = robot.getLocation().y;
junction.arrivalHeading = robot.getHeading();
junctions.add(junction);
}
}
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
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) {
I have to declare a parameter on my method final to access it through a Runnable but can I still access the methods? I need to edit the object a bit. I can't seem to find anything that can help me with this question, so hopefully this isn't a stupid question. Thanks in advanced!
An object is not final, but its reference is. So you can easily access its methods (if any) to modify the object.
You can change the state of the object, even if it is marked final. When you mark a reference variable final, you can't reassign it to another object, but you can definitely change the state of the object to which it is already referring by calling its methods.
Yes you can. Check this example
public class SampleA
{
private static final SampleB sampleB = new SampleB();
public static void main(String[] args)
{
System.out.println( sampleB.toString() );
sampleB.setM1( "1" );
System.out.println( sampleB.toString() );
}
}
public class SampleB
{
private String m1;
private String m2;
public String getM1()
{
return m1;
}
public void setM1(String m1)
{
this.m1 = m1;
}
public String getM2()
{
return m2;
}
public void setM2(String m2)
{
this.m2 = m2;
}
public String toString()
{
final String TAB = " ";
String retValue = "SampleB ( "
+ "m1 = " + this.m1 + TAB
+ "m2 = " + this.m2 + TAB
+ " )";
return retValue;
}
}