Im building a lexical/syntex analyzer for class. The problem I am having is when I try to access my static variable "lexems" or "tokens" from a method besides main they are NULL. When I use them in main (such as the lex.printList method) they are fine and filled with data.
Whats going on???
import java.io.IOException;
import java.util.ArrayList;
public class SyntaxAnalyzer {
public static int pos = 0;
public static ArrayList<String> lexems = new ArrayList<String>();
public static ArrayList<String> tokens = new ArrayList<String>();
public static String nextToken;
public static void main(String[] args) throws IOException {
LexicalAnalysis lex = new LexicalAnalysis();
lex.getFile();
lex.parseText();
ArrayList<String> lexems = lex.getLexems();
lex.printList(lexems);
ArrayList<String> tokens = lex.getTokens();
lex.printList(tokens);
//expr();
lex();
}
static void lex(){
//String lexem = lexems.get(pos);
//System.out.println(lexem);
nextToken = tokens.get(pos);
pos++;
}
}
You are overriding the lexems object with the local one so it is not static variable you are modifying inside main function.
To operate on the static one you should do
/*NOTHING HERE!!*/ lexems = lex.getLexems();
lex.printList(lexems);
...
The same issue with tokens occurs
/*NOTHING HERE!!*/ tokens = lex.getTokens();
lex.printList(tokens);
...
The problems are here:
ArrayList<String> lexems = lex.getLexems();
lex.printList(lexems);
ArrayList<String> tokens = lex.getTokens();
In you main function you do not modify the static variables but local ones (local in the main function).
Just change it to that:
lexems = lex.getLexems();
tokens = lex.getTokens();
You are creating another pair of variables in your main method, which happen to have same names as your static variables, and "overshadow" them within the scope of main method.
To fix it, you should not declare new variables, but initialise the existing ones:
public static void main(String[] args) throws IOException {
LexicalAnalysis lex = new LexicalAnalysis();
lex.getFile();
lex.parseText();
lexems = lex.getLexems();
lex.printList(lexems);
tokens = lex.getTokens();
lex.printList(tokens);
//expr();
lex();
}
This should help make the difference between the scopes used in your code :
public class MyClass{
private static int myInt;
public static void main(String[] args){
int myInt = 6;
printMyInt();
}
static void printMyInt(){ System.out.println(myInt); } // Prints 0 because uses the class field
}
Related
I often struggle with non-static variable errors. Not sure I have understood the purpose properly when to use static and not. I have the below code where I'm trying to parse a csv file with three columns (date, time, temperature) in to a class I have defined myself.
This bit gives me a non-static variable error.
TempData objt = new TempData();
If anyone knows what I'm doing wrong I'd be very grateful. I've tried google but can't find anything relevant.
package com.company;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.text.SimpleDateFormat;
import java.sql.Timestamp;
public class Main {
public static void main(String[] args) {
Date tempDate;
Date tempTime;
Double tempTemperature;
ArrayList<TempData> data = new ArrayList<TempData>();
TempData objt = new TempData();
//Get scanner instance
Scanner scanner = new Scanner(new File("smhi-opendata.csv"));
//Set the delimiter used in file
scanner.useDelimiter(";");
//Get all tokens and store them in some data structure
while (scanner.hasNext())
{
tempDate = new SimpleDateFormat("dd/MM/yyyy").parse(scanner.next());
tempTime = new SimpleDateFormat("hh:mm:ss").parse(scanner.next());
tempTemperature = Double.parseDouble(scanner.next());
objt.Data(tempDate, tempTime, tempTemperature);
data.add(objt);
}
//Do not forget to close the scanner
scanner.close();
}
public class TempData{
private Date date;
private Date time;
private double temperature;
public void Data (Date d, Date t, double te){
date = d;
time = t;
temperature = te;
}
}
}
First off the Data function just updates the values rather than create a new TempData object. Secondly the main function can't use the TempData class where it is currently.
I'd go for something like this instead:
public class TempData {
private Date date;
private Date time;
private double temperature;
public TempData(Date date, Date time, double temperature) {
this.date = date;
this.time = time;
this.temperature = temperature;
}
public static void main(String[] args) throws Exception {
Date tempDate;
Date tempTime;
Double tempTemperature;
ArrayList<TempData> data = new ArrayList<TempData>();
// Get scanner instance
Scanner scanner = new Scanner(new File("smhi-opendata.csv"));
// Set the delimiter used in file
scanner.useDelimiter(";");
// Get all tokens and store them in some data structure
while (scanner.hasNext()) {
tempDate = new SimpleDateFormat("dd/MM/yyyy").parse(scanner.next());
tempTime = new SimpleDateFormat("hh:mm:ss").parse(scanner.next());
tempTemperature = Double.parseDouble(scanner.next());
TempData objt = new TempData(tempDate, tempTime, tempTemperature);
data.add(objt);
}
// Do not forget to close the scanner
scanner.close();
}
}
The problem is that you are accessing a non static class from a static context. The main method (public static void main() {}) has the keyword static so it is in the class (static) context. Your inner class TempData is not static, so it belongs to the instance (non static) context.
You can access the class context from instance context, but not vice versa. So you have tow options:
Move your TempData class to the static context:
public class Main {
public static void main(String[] args) {
// ...
TempData objt = new TempData();
// ...
}
public static class TempData{
// ...
}
}
Or access your TempData from non static context. For example:
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
// ...
TempData objt = new TempData();
// ...
}
public class TempData {
// ...
}
}
To read more about this you can follow this official explanation.
disclaimer: Sorry if I used the terms incorrectly. It would be great if you could provide the correct terms (if I used them incorrectly!)
This is my class with the field and constructor:
double[] studentMathScores = {81.5,89.0,45.5,99.0,55.0,34.5,56.0,78.0,76.0,80.0};
public StudentDashboard(double[] studentMathScores)
{
this.studentMathScores = studentMathScores;
}
How do I declare an object in my main class using studentMathScores?
StudentDashboard test = new StudentDashboard(studentMathScores);
`
If you want to keep current constructor/class syntax you should declare in your main method.
double[] studentMathScores = {81.5,89.0,45.5,99.0,55.0,34.5,56.0,78.0,76.0,80.0};
In this case your declaration of studentMathScores in StudentDashboard shoul look like double[] studentMathScores;
Then have it like this:
public class Main {
public static void main(String[] args) {
double[] studentMathScores = {81.5,89.0,45.5,99.0,55.0,34.5,56.0,78.0,76.0,80.0};
StudentDashboard test = new StudentDashboard(studentMathScores);
}
}
If class syntax could be changed and studentMathScores can be static you can have it this way:
public class StudentDashboard {
static double[] studentMathScores ={81.5,89.0,45.5,99.0,55.0,34.5,56.0,78.0,76.0,80.0};
public StudentDashboard()
{
}
public static double[] getStudentMathScores() {
return studentMathScores;
}
public class Main {
public static void main(String[] args) {
StudentDashboard test = new StudentDashboard();
double[] studentMathScores = StudentDashboard.getStudentMathScores();
}
}
I'll start of with the OOP concepts.
this is how Declaration is done:
StudentDashboard test;
Now i'll initialize the object by assigning it the constructor of the class. Also providing constructor the required parameter of an array:
StudentDashboard test = new StudentDashboard(studentMathScores);
now whenever i'll need to use this array from this object this is how it will be done.
double Singleindex = test.studentMathScores[1];
double[] wholeArray = test.studentMathScores;
I have two separate files, one named WonderfulArrayList, and the other named ArrayListMain (I'm experimenting with ArrayLists, and I'm not quite sure what to do) and so I have a method in the WonderfulArrayList file, but the main file cannot see the method, which I have named booladdData, which would return true once the data is added to the array list. My WonderfulArrayList file is the following:
import java.util.*;
import java.io.*;
public class WonderfulArrayList{ //implement WonderfulArrayList
public static int ADDNums;
public static int index;
public static int HEADNums;
public static ArrayList<Integer> arr = new ArrayList<Integer>(15);
public static boolean booladdData(ArrayList<Integer>arr){
arr.add(ADDNums);
return true;
}
}
As you can see, I have booladdData instantiated with the ArrayList, named arr. Now, if you look at my main file:
public class ArrayListMain{
//public ArrayList<Integer> arr = new ArrayList<Integer>(15);
public static void main(String[]args){
ArrayList<Integer> arr = new ArrayList<Integer>(15);
int MenuNum = 0;
int ADDNums = 0;
Object Obj = new Object();
Scanner scanner1 = new Scanner(System.in); //set up scanner for user input
while(MenuNum != 7){ //menu loop
Menu(MenuNum);
MenuNum = scanner1.nextInt();
if(MenuNum == 1){
arr.booladdData();
}
For some reason, even though I know that booladdData is created as public and they're both in the same folder, the main file doesn't have the scope to be able to see booladdData in the separate file.
Any idea what I'm doing wrong?
You should be calling WonderfulArrayList.booladdData(arr) instead of arr.booladdData(). The method booladdData() is defined as a class method of your WonderfulArrayList class. It's not an instance method of Java's ArrayList.
You also might want to read into object-oriented programming. Everything in your code is static.
You need to create your type instead of ArrayList
package com.jbirdvegas.test;
import java.util.ArrayList;
public class MainClazz {
public static void main(String[] args) {
// notice I'm creating my type `MyArrayList` instead of `ArrayList` type
MyArrayList myArrayList = new MyArrayList();
myArrayList.add("blah");
System.out.println("My message:" + myArrayList.getSomething());
}
}
class MyArrayList extends ArrayList {
public String getSomething() {
return "something";
}
}
Prints:
My message: something
Im stuck with the following problem,
I've two classes, the first is readFromFile and the second class is newClass
readFromFile.java -
This reads a text file
Parses the lines of text into seperate strings
The values of these strings are stored in a String [ ] called dArray
For testing I've printed all values out and it works
newClass.java
This class is intended to copy the value of the string [ ] dArray into a new string and from there use the values ( for simplicity all I've included in the newClass is the code relating to copying the array)
What I'm doing wrong is that I'm returning dArray but its returning an array with nothing stored in it, so I either need a way to call main method from readFromFile.class / help creating a method in readFromFile that would do the same which I call from main
please help
import java.util.Scanner;
import java.io.*;
public class readFromFile
{
static String[] dArray = new String [30];
public static void main (String[] args) throws IOException
{
String part;
Scanner fileScan, partScan;
int i = 0;
int x = 0;
fileScan = new Scanner (new File("C:\\stuff.txt"));
// Read and process each line of the file
while (fileScan.hasNext())
{
part = fileScan.nextLine();
partScan = new Scanner (part);
partScan.useDelimiter(":");
while ( partScan.hasNext()){
dArray[i] = partScan.next();
i++;
}
}
for (x = 0;x<i;x++)
{ System.out.println(dArray[x]);
}
}
public String[] getArray()
{
return dArray;
}}
newClass.java
public class newClass {
readFromFile results = new readFromFile();// creating object from class readFromFile
public void copyArray() {
String[] dArray = results.getArray(); // Trying to return the values of String [] dArray from rr classs
//Method getArray in rr class is
// public String[] getArray()
// { return dArray; }
String[] arrayCopy = new String[dArray.length];
System.arraycopy(dArray, 0, arrayCopy, 0, dArray.length);
for (int i = 0; i < arrayCopy.length; i++)
System.out.println(arrayCopy[i]);
}
public static void main(String[] args) {
newClass.copyArray();
}
}
Your results generation is in readFromFile.main(), but you're expecting to call it in your readFromFile(). You need to make a constructor for readFromFile, and call that in your main method, as well.
The problem is that both classes have a main method. Only the class that you intend to run should have a main method, the other classes need only constructors. Assuming you want to run a unshown class it would be written like this.
public class ThirdClass{
public static void main(String[] args) {
readFromFile reader = new ReadFromFile();
newClass copy = new newClass();
reader.readFromFile();
String[] strings = reader.getArray();
copy.copyArray(strings)
}
For this to work you need to put all of the code in the main of readFromFile in a method called "readFromFile". and you need a method in newClass that accepts a string array as an argument. Or a constructor that accepts a string array.
Make sure that neither of them have main methods or it won't work.
Remove the static keyword before your dArray variable
Change public static void main(String[] args) throws IOException in your first class to public readFromFile() throws IOException. Keep the code inside it the same.
Change the line newClass.copyArray(); in your second class to (new newClass()).copyArray();
Move the line in your second class readFromFile results = new readFromFile(); into the public void copyArray() method.
Change public void copyArray() in your second class to public void copyArray() throws IOException
Put a try..catch block around your code in the second class's main method. i.e. change (new newClass()).copyArray(); to something like try { (new newClass()).copyArray(); } catch (IOException e) { e.printStackTrace(); }
The above should get your thing working, but a friendly note would be to experiment with the code (once it works) since it's an excellent example to understand how static keywords are used, how Exceptions are handled or thrown, and how IO is used. ;)
I'm trying to create a class with static variables, but I'm not sure how to set the variables before runtime. This is what I'm attempting to do...
public class Defaults {
public static String[] abc = new String[2];
public static void functionToExecuteBeforeRuntime{
abc[0] = "a";
abc[1] = "b";
abc[2] = "c";
}
}
It's supposed to set abc using functionToExecuteBeforeRuntime before runtime so other classes can access it with Defaults.abc,however it is never executed. How can I achieve this? Any help appreciated
-oh i'm not sure if this makes a difference but I don't think with andriod I can use the public static main() guy
For that example, you could just initialize it there, like:
public static String[] abc = new String[]{"a", "b", "c"};
For just a general way of doing complex initialization for your static fields, I'm not sure, but I believe Android has Static Initializer Blocks, which work like:
public class Test
{
public static String[] stuff = new String[2];
static
{
stuff[0] = "Hi";
stuff[1] = "Bye";
}
}
Or you could use static functions to do, basically, the same thing.
public class Test
{
public static String[] stuff = initializeStuff();
public static String[] initializeStuff()
{
String[] arr = new String[2];
arr[0] = "Hi";
arr[1] = "Bye";
return arr;
}
}
Put it into a static initialization block of code like so:
private static String[] stuff;
static {
stuff = new String[] {"1", "2"};
}