very specific java constructors and Object class problem - java

I have an array at actionTable.get(state).
When I go to add an onject to the array, namely the Reduce, the properties of the reduce don't seem to go with it.
The array is of type Action[] where Action is the superclass of Reduce, could this be the reason?
Adding the reduce to the array:
actionTable.get(state)[t] = new Reduce(st.items.get(item).prod);
Checking to see if the field head is defined before adding it:
System.out.println(Prod.prods.get(st.items.get(item).prod).head);
Checking to see if the newly added reduce has the correct head field:
System.out.println(actionTable.get(state)[t].prod.head);
A NullPointerException occurs on the last print statement. The .prod part is defined but the .prod.head is null, even though the original prod object had a defined head.
This is the constructor for Reduce:
Reduce(int pr) {
p = pr;
length = Prod.prods.get(pr).length;
prod = Prod.prods.get(pr);
}
All of the RHS of the assignments in the constructor are defined. So, I don't understand why the head field, within the prod object that the new Reduce has access to is not defined when you access it through the actionTable.

Trust inheritance and all. Most likely with arrays is, that different array instances are involved (if you enlarge/copy array references). Some more System.out.println's will help there.

The first thing you always should do is this: got to your break points view in your IDE, check "stop on Exception thrown" and perhaps give the name NullPointerException.
Then run your code in the debugger and it will stop exactly at the point where the NullPointerException is thrown.

Related

Java List/Array List clarification

If someone can explain the difference between these two type of Array Initializations that would be great:
There is a static method getList() in class ListReturn, which returns an ArrayList<Some_Custom_Object> upon calling.
In the invoking class, I can call the function in two ways as follows:
List<Some_Custom_Object> listFromCall = new ArrayList<Some_Custom_Object>();
listFromCall=ListReturn.getList();//works completely fine
List<Some_Custom_Object> listFromCall = ListReturn.getList();//Works completely fine
My question here is, in the second scenario, don't we have to initialize or instantiate the listFromCall object?, can we directly assign return values from method to un-initialized List/ArrayList object?
Can someone please explain what is going on beneath the hood here?.
Thanks
You only have to initialize a variable if you read from it before you write to it.
If you write to an uninitialized variable, the computer doesn't care because you're initializing it with the return value from ListReturn.getList().
In fact, you shouldn't needlessly initialize object variables to anything but null if they're going to be overwritten before use. Otherwise, you create and garbage collect an extra object for no reason.
Let's discuss both way one by one,
First Way :
List<Some_Custom_Object> listFromCall = new ArrayList<Some_Custom_Object>();
means, something likewise,
listFromCall=ListReturn.getList();//works completely fine
it will reflect on listFromCall's value assignment, see below image for
deeper understanding,
Here, completion of both statement, total either 2-object created(1
will eligible for garbage collection after second created and assign)
or 1-object created (which will become eligible for garbage collection
and assign null to reference variable)
Your Second Way :
Now if you do something likewise,
2. List<Some_Custom_Object> listFromCall = ListReturn.getList();//Works completely fine
Then it will appear something likewise,
So, here either 1-object(of ArrayList) will created on heap or not.

Hashtable NullPointerException

I have an assignment to design a simple spam filter using a hash table to store a set of "bad words." We discussed in class what a hash table is and how it's used (ie. how elements are inserted, linear probing, quadratic probing, chained probing, etc.), but we never really discussed how to use the Java API Hashtable, which is required for this assignment. anyway, I've tried my best to implement it, however, I'm getting an exception that I cannot seem to trace with my debugger.
I've given up with inserting code here, I always have to spend time formatting it properly and it still doesn't look good. So I'm putting it on Pastebin instead. It should make your lives easier too since it does syntax highlighting and line counting as well.
SpamFilter class
SpamFilterDriver class
I get NullPointerExceptions at the following lines in the SpamFilterDriver class:
line 78
line 96
line 115
Any help would be appreciated. I'm sure it's probably something silly, but I'm just not seeing it at the moment.
Also, please note that the code is not finished yet in the least. The fact that the SpamFilter implements Serializeable will be used later on. Also, there are some empty methods, again, they will be implemented later, I just need to solve this problem first.
you have to initialize your SpamFilter filter; in your SpamFilter Class. before calling any of its methods.
on line 78, you are calling a method isBadWord().
try initializing filter like below before calling any of its method. if you dont initialize your filter the default value is null and boom when you call a method with null BOOM BOOM NPE is thrown
private static SpamFilter filter = new SpamFilter();//
In each one of those lines, observe that you are invoking a method of filter. Java is throwing getting a NullPointerException because filter's value is null.
Why is its value null? Because you never assigned it a value; you merely declared it. You can set its value right as you declare it or, since it's a static field, you can use a static constructor to assign it a value.
Your filter is not be initialized hence failing wherever its being used. Its only declared in the top as private static SpamFilter filter;, which makes filter as null.
To fix the problem, initialize the filter either at declaration as
private static SpamFilter filter = new SpamFilter();
or in main() method before while loop as
filter = new SpamFilter();
Looks like you never initialize the filter property, so you get a NullPointerException whenever you try and use it.
Try replacing line 6 with:
private static SpamFilter filter = new SpamFilter();

Initialize an ArrayList. When necessary?

I had the impression growing out of the applications by my work that when I define an ArrayList attribute in a class in Java 7, it is not necessary to initialize it (with new as a new Object) when I want to access it in a method for the first time. Nevertheless I receive always a nullPointerException error (on my personal home Computer), despite of having installed JDK1.7.0. Is there a newer version which I should install to overcome this annoying occurrence?
public class AdditionNode {
private VectorOperationCodeGen nodeCodeGen;
protected ArrayList<VectorInTree> connectedVectors;
...
...
...
public void inputVector(VectorInTree inputVector){
if(inputFlag==2||inputFlag==0){
if(this.connectedVectors.isEmpty()){
The last line evokes a nullPointerException. Should be so?
I define an ArrayList attribute in a class in Java 7, it is not
necessary to initialize it (with new as a new Object) when I want to
access it in a method for the first time.
This is false. What gave you that impression ?
I had the impression growing out of the applications by my work that when I define an ArrayList attribute in a class in Java 7, it is not necessary to initialize it
If you are to use the ArrayList, then you better initialize it.
By simply doing
ArrayList<SomeType> list;
you have just declared a reference to an ArrayList, and not actually created an ArrayList.
If you want to be "lazy" with the initialization, then whenever you need to access the list referred to by list, you'll have to do
ArrayList<SomeType> list;
// ...
if (list == null)
list = new ArrayList<SomeType>();
list.add(someElement);
Since the very beginning of Java the default value for references (which you call "ArrayList attribute") has been null. This will also not change in the future. Therefore someone must initialize them before using the list.
So this one simple declares a list reference and initializes it with null:
class MyClass {
private ArrayList<String> list;
}
To declare and initialize it with an actual instance just do:
class MyClass {
private ArrayList<String> list = new ArrayList<String>();
}
At Work you might use some frameworks, which can do nearly magical things for you. Better check out what framework are used and learn how they do their magic and, most importantly, when they do and when they don't do this magic.
If I can say my opinion, yours it's a very strange impression. How can you use an object(such as an array list) without initialization and declaring a reference? Only referencing an object and initializing it, you can use that object.
If it would be possible what you're saying, it isn't necessary to have a reference of something on the memory and you have solved the problems of memory allocation. :-)
You should be clearer in your question.
EDIT
Now you have updated the question.
Yes, it should be like you are saying. You are receiving NullPointerException from the compiler on the line if(this.connectedVectors.isEmpty()){, because you haven't initialized before with new operator the connectedVectors object.
If you are at the beginning with java programming, this is considered a typical error, and for now you are forgived :-)
Even if the forgotten initialization of an object is considered a typical error of beginner programmer, this is an important and serious error, that you must not repeat.
As far as i know, you can't avoid to initialize an object before using it.
Even if this is true, you should initialize it anyway because if your user does not use the java version you're referring, he's gonna meet a lot of errors.
Still, I don't think that you can do what you're saying.
This 'annoying occurrence' is part of the design of the Java Programming Language, and hasn't changed since the beginning. Your expectations/impressions are mistaken.

Learning C++ from Java , trying to make a linked list

I just started learning C++ (coming from Java) and am having some serious problems with doing anything :P Currently, I am attempting to make a linked list, but must be doing something stupid cause I keep getting "void value not ignored as it ought to be" compile errors (I have it marked where it is throwing it below). If anyone could help me with what I'm doing wrong, i would be very grateful :)
Also, I am not used to having the choice of passing by reference, address, or value, and memory management in general (currently I have all my nodes and the data declared on the heap).
If anyone has any general advice for me, I also wouldn't complain :P
Key code from LinkedListNode.cpp
LinkedListNode::LinkedListNode()
{
//set next and prev to null
pData=0; //data needs to be a pointer so we can set it to null for
//for the tail and head.
pNext=0;
pPrev=0;
}
/*
* Sets the 'next' pointer to the memory address of the inputed reference.
*/
void LinkedListNode::SetNext(LinkedListNode& _next)
{
pNext=&_next;
}
/*
* Sets the 'prev' pointer to the memory address of the inputed reference.
*/
void LinkedListNode::SetPrev(LinkedListNode& _prev)
{
pPrev=&_prev;
}
//rest of class
Key code from LinkedList.cpp
#include "LinkedList.h"
LinkedList::LinkedList()
{
// Set head and tail of linked list.
pHead = new LinkedListNode();
pTail = new LinkedListNode();
/*
* THIS IS WHERE THE ERRORS ARE.
*/
*pHead->SetNext(*pTail);
*pTail->SetPrev(*pHead);
}
//rest of class
The leading * in
*pHead->SetNext(*pTail);
*pTail->SetPrev(*pHead);
are not needed.
pHead is a pointer to a node and you call the SetNext method on it as pHead->SetNext(..) passing an object by reference.
-> has higher precedence than *
So effectively you are trying to dereference the return value of the function SetNext which does not return anything, leading to this error.
Also, I am not used to having the choice of passing by reference, address, or value, and memory management in general (currently i have all my nodes and the data declared on the heap). If anyone has any general advice for me, i also wouldn't complain :P
Ex-Java programmers always do that. And it's upside down.
You should virtually never heap-allocate data. Objects should be declared on the stack, and if they need heap-allocated memory, they should handle that internally, by allocating it in their constructors and releasing it in their destructors.
That leads to cleaner and safer code.
Class members should also be values, not pointers/references unless you specifically need the member to be shared between different objects. If the class owns its member exclusively, just make it a non-pointer value type. That way it's allocate inside the class itself, and you don't need to keep track of new/delete calls.
The simplest rule of thumb is really to not use pointers unless you have to. Do you need the object to be allocated elsewhere? Why can't it be allocated here and be accessed by value? Even if the object has to be returned from a function, or passed as parameter to another function, copying will usually take care of that. Just define appropriate copy constructors and assignment operators and copy the object when necessary.

Why does javac complain about not initialized variable?

For this Java code:
String var;
clazz.doSomething(var);
Why does the compiler report this error:
Variable 'var' might not have been initialized
I thought all variables or references were initialized to null. Why do you need to do:
String var = null;
??
Instance and class variables are initialized to null (or 0), but local variables are not.
See ยง4.12.5 of the JLS for a very detailed explanation which says basically the same thing:
Every variable in a program must have a value before its value is used:
Each class variable, instance variable, or array component is initialized with a default value when it is created:
[snipped out list of all default values]
Each method parameter is initialized to the corresponding argument value provided by the invoker of the method.
Each constructor parameter is initialized to the corresponding argument value provided by a class instance creation expression or explicit constructor invocation.
An exception-handler parameter is initialized to the thrown object representing the exception.
A local variable must be explicitly given a value before it is used, by either initialization or assignment, in a way that can be verified by the compiler using the rules for definite assignment.
It's because Java is being very helpful (as much as possible).
It will use this same logic to catch some very interesting edge-cases that you might have missed. For instance:
int x;
if(cond2)
x=2;
else if(cond3)
x=3;
System.out.println("X was:"+x);
This will fail because there was an else case that wasn't specified. The fact is, an else case here should absolutely be specified, even if it's just an error (The same is true of a default: condition in a switch statement).
What you should take away from this, interestingly enough, is don't ever initialize your local variables until you figure out that you actually have to do so. If you are in the habit of always saying "int x=0;" you will prevent this fantastic "bad logic" detector from functioning. This error has saved me time more than once.
Ditto on Bill K. I add:
The Java compiler can protect you from hurting yourself by failing to set a variable before using it within a function. Thus it explicitly does NOT set a default value, as Bill K describes.
But when it comes to class variables, it would be very difficult for the compiler to do this for you. A class variable could be set by any function in the class. It would be very difficult for the compiler to determine all possible orders in which functions might be called. At the very least it would have to analyze all the classes in the system that call any function in this class. It might well have to examine the contents of any data files or database and somehow predict what inputs users will make. At best the task would be extremely complex, at worst impossible. So for class variables, it makes sense to provide a reliable default. That default is, basically, to fill the field with bits of zero, so you get null for references, zero for integers, false for booleans, etc.
As Bill says, you should definitely NOT get in the habit of automatically initializing variables when you declare them. Only initialize variables at declaration time if this really make sense in the context of your program. Like, if 99% of the time you want x to be 42, but inside some IF condition you might discover that this is a special case and x should be 666, then fine, start out with "int x=42;" and inside the IF override this. But in the more normal case, where you figure out the value based on whatever conditions, don't initialize to an arbitrary number. Just fill it with the calculated value. Then if you make a logic error and fail to set a value under some combination of conditions, the compiler can tell you that you screwed up rather than the user.
PS I've seen a lot of lame programs that say things like:
HashMap myMap=new HashMap();
myMap=getBunchOfData();
Why create an object to initialize the variable when you know you are promptly going to throw this object away a millisecond later? That's just a waste of time.
Edit
To take a trivial example, suppose you wrote this:
int foo;
if (bar<0)
foo=1;
else if (bar>0)
foo=2;
processSomething(foo);
This will throw an error at compile time, because the compiler will notice that when bar==0, you never set foo, but then you try to use it.
But if you initialize foo to a dummy value, like
int foo=0;
if (bar<0)
foo=1;
else if (bar>0)
foo=2;
processSomething(foo);
Then the compiler will see that no matter what the value of bar, foo gets set to something, so it will not produce an error. If what you really want is for foo to be 0 when bar is 0, then this is fine. But if what really happened is that you meant one of the tests to be <= or >= or you meant to include a final else for when bar==0, then you've tricked the compiler into failing to detect your error. And by the way, that's way I think such a construct is poor coding style: Not only can the compiler not be sure what you intended, but neither can a future maintenance programmer.
I like Bill K's point about letting the compiler work for you- I had fallen into initializing every automatic variable because it 'seemed like the Java thing to do'. I'd failed to understand that class variables (ie persistent things that constructors worry about) and automatic variables (some counter, etc) are different, even though EVERYTHING is a class in Java.
So I went back and removed the initialization I'd be using, for example
List <Thing> somethings = new List<Thing>();
somethings.add(somethingElse); // <--- this is completely unnecessary
Nice. I'd been getting a compiler warning for
List<Thing> somethings = new List();
and I'd thought the problem was lack of initialization. WRONG. The problem was I hadn't understood the rules and I needed the <Thing> identified in the "new", not any actual items of type <Thing> created.
(Next I need to learn how to put literal less-than and greater-than signs into HTML!)
I don't know the logic behind it, but local variables are not initialized to null. I guess to make your life easy. They could have done it with class variables if it were possible. It doesn't mean you have to have it initialized in the beginning. This is fine :
MyClass cls;
if (condition) {
cls = something;
else
cls = something_else;
Sure, if you've really got two lines on top of each other as you show- declare it, fill it, no need for a default constructor. But, for example, if you want to declare something once and use it several or many times, the default constructor or null declaration is relevant. Or is the pointer to an object so lightweight that its better to allocate it over and over inside a loop, because the allocation of the pointer is so much less than the instantiation of the object? (Presumably there's a valid reason for a new object at each step of the loop).
Bill IV

Categories

Resources