programming error in java due to static variable - java

Following code is going in else statement. I am not able to find out where i made mistake.
*A want to execute in below comments.
*B is executing in below comments.
package com.java;
import java.util.Scanner;
public class Solution
{
static int n;
static String w[];
public static void main(String[] args)
{
System.out.println("enter no of string between 1 to 50");
Scanner scanner = new Scanner(System.in);
//* A
if ((1<n) && (n<=50))
{
n = scanner.nextInt();
System.out.println("enter " +n+ "strings between 1 to 2000 length");
for (int i=0; i<n; i++)
{
w[i]= scanner.next();
if ((1<w[i].length()) && (w[i].length()<2000))
{
System.out.println("ok");
}
}
System.out.println(w);
}
// *B
else
{
System.out.println("coming due to static");
}
}
}

static means that it is a class variable, that is, it does not belong to an instance of the class. And opposite, a non static variable belongs to an instance of the class. You're referencing the variable n from a static method, and hence, it will not work unless the variable also is declared static.
(and obviously, the if itself won't work because of what the reply from #MarounMaroun mention)

You didn't initialize n, so you're not satisfying the if condition, since uninitialized static int variables are 0 by default.
So:
if ((1<n) && (n<=50)) is not evaluated to true, so else will be executed.
Note that you can't access static variable from non-static method (See #NilsH answer). And that's make a lot of sense..

First, when working with static methods, you must reference static variables. If you try to reference a non-static variable that belongs to a class, the compiler will complain because that is wrong. Static variables do not belong to a class per se.
Second, I think you have a typo or forgot some code. n is never set - ever. Therefore, since in the static context it will be zero initialized and hit the else. I think you meant for n to actually be set before the if statement either via user-input or some other means. If you leave everything static and actually provide a value for n, then your code should work.
For instance, you probably need to make this assignment:
n = scanner.nextInt();
before the if-statement.
there is another problem with your code in reading the next number you want to read, but I will leave that for you to solve.

Have you tried making static int n and static String w[] public?
IE:
public static int n ;
public static String w[] ;

what you probably want is moving all that code to a non-static method. and then in your main method just do something like this
Solution s = new Solution();
s.myNonStaticMethod();

Related

Counter loop and average

I want to enter marks of 5 subjects in an array and calculate their average and run the counter loop 5 times and then display the name and average.
package enstudentrunner;
import java.util.Scanner;
public class EnStudent {
private String Name;
public int[] Result_array=new int[5];
public EnStudent(String Name,int Result_array[])
{ this.Name=Name;
for(int count=0;count<Result_array.length;count++)
{
Scanner input = new Scanner (System.in);
System.out.println("Enter marks");
Result_array[count]=input.nextInt();
}
}
public int Average()
{
int total=0;
for(int counter=0;counter<Result_array.length;counter++)
{
total+=Result_array[counter];
}
return total/5;
}
public void display()
{
System.out.println("your name is"+this.Name+"average is"+Average());
}
}
package enstudentrunner;
public class EnStudentRunner {
public static void main(String[] args) {
// TODO code application logic here
int[] Result_array=new int[5];
EnStudent Std = new EnStudent("Usama",Result_array);
Std.Average();
Std.display();
}
}
I expect the output of {50,60,70,80,90} to be 70 but the actual output is 0
You are passing the Result_array from your main and updating that array instead of using this.Result_array. There is no point in passing the Result_array.
So, some tips about coding convention first. In java and most languages, please start you variable with a lower case letter. It increases readability.
So the problem you are having is scoping of variables.
In you constructor
public EnStudent(String Name,int Result_array[])
you referenced Result_array. The way java scoping works is that it always reference the variable with the smallest scope. So in this case, the local variable (argument) Result_array is used. Thus the values are stored in the array you passed in. The problem comes when you compute the average, you are referencing the array you created inside the EnStudent class. (Member variable) Which is never assigned to, it is all empty.
There are two options to fix this:
1) You could remove the parameter Result_array in your construction. It seems redundant.
2) You could assign this argument to the member variable Result_array. (And if you do this, the member variable does not need to be initialized.)
Hope you find this helpful.

Why forward referencing only possible in methods

What is happening in the compiler when we do forward referencing methods, how does it assign the value of another variable which is not declared? And can we use that inside methods? But why can we not use the variable in static blocks? For example,
public class Forward {
static int i = test();
static int test() {
System.out.println(j);
j = 20;
return j;
}
static {
System.out.println(j);
j = 20;
}
static int j;
}
If we assign the value directly like:
int i = j;
int j = 10;
Why does this code not compile? How is it possible only with methods? How does the compiler compile the forward references internally? Is the declaration happening first for all the variables and initialization happening next for all at a time or one by one? Explain it in detail.
JLS Section 8.3.3 states that 4 criteria must all be met if the forward-usage of a static variable will be considered a compile-time error:
The declaration of a class variable in a class or interface C appears textually after a use of the class variable;
In other words, obviously, it must be a "forward declaration": you use it before you declare it:
// Maybe not OK to use j here.
static int j;
// OK to use j here.
The use is a simple name in either a class variable initializer of C or a static initializer of C;
You can make a forward reference to the variable if you qualify its name:
static {
System.out.println(j); // Error on this line...
System.out.println(Forward.j); // ...but not this line...
System.out.println(org.whatever.Forward.j); // ...or this line...
}
static int j;
This criterion only applies to variable or static initializers. This answers the specific question of why you are not getting a compiler error when referring to the static variable in a method.
However, let's just finish things off...
The use is not on the left hand side of an assignment;
Note in this code:
static {
System.out.println(j); // Error on this line...
j = 20; // ...but not this line.
}
static int j;
You can't do anything except assign the variable, even if you reverse the order of the lines (you can't assign and then print it).
C is the innermost class or interface enclosing the use.
The following code would be fine:
class Forward {
static class Inner {
static {
System.out.println(j);
}
}
static int j;
}

Calling another class in Java

OK, so what I want to do is create 2 classes. One is main class and the second class is to make a loop sentinel control and then return the total of it till the user enters 0. I couldn't get it to work. I don't know how to call the other class because I'm very new to Java. Here's what I have.
Class 1:
import java.util.*;
public class HW3 {
public static void main(String[] args) {
OrderDetails object = new OrderDetails();
int n;
n = object.OrderDetails(0);
System.out.println(n);
Class 2:
import java.util.*;
public class OrderDetails {
Scanner input = new Scanner(System.in);
int total=0;
int n1;
public int OrderDetails(int n1){
while (n1 != 0){
System.out.println("Enter your number");
n1 = input.nextInt();
total += n1;
} // End while loop
return total;
} // End method
First of all
public int OrderDetails(int n1)
You are using the name of the class as the method name, it will work and run but some IDE will complain on it that you are using the name of the class as a method that you need to change it as a constructor.
object.OrderDetails(0);
Now the problem is that you are passing 0 which will break the while statement, instead pass a different value let say -1, so you will go inside the while loop and get some values from the user.
sample:
object.OrderDetails(-1); //change the name of your method
The n1 in the class scope is an instance variable, but the parameter n1 in the method is a local scope, and so it hides the instance variable. Also, the method is named the same as the class which is bad practice.
None of this is the problem - the real problem is the caller is calling with the one value that would stop it from entering the while loop. If you called with anything other than zero, you will see it produce the desired result.

Passing a value input from main method to a private variable

I am trying to pass a value from the main method and set it to a private variable. Here is the main method that's pertinent:
import java.util.*;
public class Experiment{
private static Extension extension=new Extension();
public static void main(String[] ars);{
Scanner input=new Scanner(System.in);
System.out.print("Enter the length: ");
int length=input.nextInt;
extension.messages(length); }
}
and here's what goes with it:
public class Extension{
private int theLength;
public void Extension(int length){
theLength=length; }
public void setLength(int length){
theLength=length; }
public int getLength() {
return theLength }
public void messages(int length){
System.out.println("theLength: "+theLength);
System.out.println("Length: "+getLength(); }
}
I added the extra display because I wanted to see if the value was getting passed on correctly. When I run it, I realize that it's not; both theLength and length are set to zero despite having input different numbers. Can anyone see what I'm doing wrong? I would sincerely appreciate a thorough answer (since I am just starting out).
You are not setting the private variable length. You should call the setLength(int length) method.
change to this
System.out.print("Enter the length: ");
int length=input.nextInt;
extension.setLength(length); // this will set the private variable
extension.messages(length);
This is a lesson in encapsulation. Your issue, as #salihrkc said, is that you're never actually setting the length variable which exists in your "Extension" object. If you try to print "length" as passed in to your object, you'll see it's getting there just fine.
You act on your object using the dot operator (e.g. extension.messages(length);, to call the messages method). The key points you should be realizing is that you cannot set the objects length by just doing extension.theLength = length;. This is because of the private modifier. Instead you should be using the "getter" and "setter" methods. These functions exist within your object and therefore access to the private variables, so you can do something like extension.setLength(length); and System.out.println(extension.getLength());
Check out the two sources I linked, they'll help.
Good luck.

unable to get this class working in java on client code - no compilation errors but runtime

I have pasted my code here. below the code I give descriptin of what I am trying to do
import java.util.*;
import java.io.*;
//given a string, gives letters counts etc
public class LetterDatabase{
private String word;
private int[] charCounts;
public static final int TOTAL_LETTERS=26;
//constructor
public LetterDatabase(String word) {
this.word=word;
int[] charCounts= new int[TOTAL_LETTERS];
//this function fillup charCounts with no of occurances
//more below
fillupcharArray();
}
/*Returns a count of letters.
public int get(char letter) {
return charCounts[Character.getNumericValue(letter)-10];
}
/*Sets the count for the given letter to the given value.
public void set(char letter,int value) {
int index=Character.getNumericValue(letter-'a');
charCounts[index]=value;
}
/* converts string to Array of chars containing only alphabets
private char[] convertToArray() {
String str = word.replaceAll("[^a-zA-Z]+", "");
char[] charArr=new char[str.length()];
for (int i = 0; i < str.length(); i++) {
charArr[i] = str.charAt(i);
}
return charArr;
}
private void fillupcharArray(){
char[] charArr=convertToArray();
for(int i=0;i<charArr.length;i++) {
for(int j=0;j<26;j++) {
if (Character.toLowerCase(charArr[i])==Character.toLowerCase((char)('a'+j))) {
charCounts[j]+=1;
}
}
}
}
}
my client code that I used to test is below
import java.util.*;
import java.io.*;
public class Testdatabase{
public static void main(String args[]) {
String str="my name is Dummy!!!:..,";
LetterDatabase first= new LetterInventory(str);
System.out.println(first.get('a'));
System.out.println(first.set('a'));
System.out.println(first.get('a'));
}
}
Explanation: I define a LetterDatabase class which computes the count of letters--only alphabets (type char) in given string. I have a get method, that returns the occurance of particular letter and a set method, that sets the value of letter to a set value.
in my constructor, I am calling a function that fills the array(charCounts), so that I can easily lookup for occurrence of a given char. Firstly my constructor does not work. my class code compiles and my client code above compiles. when I run the clientcode, commenting out the getter and setter calls, i get the following error.
Exception in thread "main" java.lang.NullPointerException
at LetterDatabase.fillupcharArray(LetterInventory.java:55)
at LetterDatabase.<init>(LetterInventory.java:17)
at Testdatabase.main(hw1test.java:7)
I am unable to figure what is going wrong. the fillupcharArray seems to work fine when I test it individually. I am not pasting that here.
secondly, the way I define get and set method in my class is not very good. it would be nice if I dont have to use Character.getNumericValue
I am open to hear on any other improvements. Thanks for your time
You are shadowing the array charCounts in the constructor of LetterDatabase. Replace
int[] charCounts = new int[TOTAL_LETTERS];
with
charCounts = new int[TOTAL_LETTERS];
Inside a class method, when a local variable has the same name as an instance variable, the local variable shadows the instance variable inside the method block. In this case the local variable charCounts is shadowing the instance variable charCounts.
From wikipedia
In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope
In your constructor, you've defined a local variable charCounts:
int[] charCounts= new int[TOTAL_LETTERS];
This shadows the instance variable charCounts, to which I think you meant to assign it.
Assign it to the instance variable charCounts like this:
charCounts = new int[TOTAL_LETTERS];
This means that, in your code, the instance variable charCounts remains null until you access and a NullPointerException results.

Categories