static method and non static method Java - java

I know I'm doing something stupid, but I cannot figure how to fix it.
The issue is inside the private method removeVowels particulry when using the vowels method.
The compiler gives
non-static variable vowels cannot be referenced from a static context
Here is my code:
public class RecursionHW2 {
String vowels;
// Part (A) First way
public static int upperCase(String myString){
return upperCaseChecker(myString , 0 );
}
public static int upperCaseChecker(String myString, int index){
int inc;
//My Base Code
if(myString.length() <= index) return 0;
if(Character.isUpperCase(myString.charAt(index)) == true) inc= 1;
else inc= 0;
return inc+upperCaseChecker(myString,index+1);
}
// First way of Solving part (B)
public static int count(String str, char a)
{
if (str.length() == 0)
return 0;
else if (str.charAt(0) == a)
return 1 + count(str.substring(1, str.length()), a);
else
return count(str.substring(1, str.length()), a);
}
//Second way of solving part (B)
public static int anotherCount(String myString, char myWord)
{
return anotherCount(myString, myWord, 0);
}
public static int anotherCount(String myString, char myWord, int index)
{
int inc;
if (index >= myString.length())
{
return 0;
}
if (myString.charAt(index) == myWord) inc =1;
else
inc = 0;
return inc + anotherCount(myString, myWord, index+1);
}
// part (C) solving
public Boolean isSorted(int[] a, int n)
{
if(n == 0 || n == 1) return true;
else
return isSorted(a, n, 1);
}
private Boolean isSorted(int[] a, int n, int cur)
{
if(cur == n) return true;
if(a[cur - 1] <= a[cur])
return isSorted(a, n, cur+1);
else
return false;
}
//part (D) Solving
public static String removeVowels(String myString)
{
return removeVowels(myString, "");
}
private static String removeVowels(String myString, String t)
{
if(myString.length() == 0) return t;
if(vowels.contains(myString.charAt(0) + ""))
return removeVowels(myString.substring(1), t);
else
return removeVowels(myString.substring(1), t + myString.charAt(0));
}
public static void main(String[] args){
//I've wrote 2 ways to solve the Second Recursive Q2
System.out.println("Method 1: Number of Occurence " + count("Hello This is Mohammad Fadin",'o'));
// System.out.println("Method 2: Number of Occurence "+ anotherCount("Hello This is Mohammad Fadin",'o'));
String s1 = "Hello WorlDD";
System.out.println("Number of Upper Cases " + upperCase(s1));
String s2 = "Hello";
System.out.println("After Vowels Removed " + removeVowels(s2));
}
}

You've "infected" your code with static from your main method. In your main method you should do something like this, so you don't have to make everything static:
public class RecursionHW2
{
public static void main(String[] args)
{
RecursionHW2 rhw2 = new RecursionHW2();
int count = rhw2.count("Hello world");
// and so on
}
}

You cannot reference an instance variable from a static context. You have to create an instance of RecursionHW2 first, or make the variable vowels static which makes more sense. Or you might consider to remove static modifier from removeVowels method.
Update:
However, your class looks like a bunch of utility methods, so you may want to make it non-instantiable (by adding a private constructor), make all of your methods static (because they clearly don't operate on object's state) and pass vowels as an additional parameter to removeVowels method.

The problem is exactly what the compiler tells you: you are referencing a non-static (instance) variable vowels from a static context. Actually, almost all your methods are static which is an extremely bad design.
Make all methods which require access to instance data (here: vowels instance variable) non-static and instantiate your class in main().

Change:
String vowels;
to:
static String vowels;

You cannot use String vowels inside your static methods because vowels is non-static. You need to add static keyword to the string, then your code will work.

you can make the variables static or just keep everything non-static and this will get solved. The bigger question you need to ask your self is when should i use static and when not ?

change
String vowels;
to
static String vowels;
All your methods are static and thus do not require an instance of your object to be present - ie you don't have to say
x = new RecursionHW2();
x.upperCase(..);
However if you don't make vowels static, it doesn't exist unless an object is instantiated.

Static variables belong to the class, the static variables that are not belong to the class instances (objects).
Test
class Foo {
private static String vowers;
private String bar;
}
Foo a = new Foo ()
Are creating a new instance of class Foo, each instance has its own variable bar, but all share vowers variable because this belongs to the class. Same goes with the static methods.
Within a static method (class method) you can not reference variables that are not static. Why is this so?
imagine that from a static method you reference a variable that is not static
class Foo {
private static String vowers;
private String bar;
public static void exampleMethod () {
bar = "home";
}
}
If you do this:
Foo a = new Foo () / / has a new bar
Foo b = new Foo () / / has a new bar
vowers is a single variable and belongs to the class not the instance
When you
Foo.exampleMethod()
The method does not know that variable bar used if the variable of instance a or the variable instance of b. Therefore you can only access static variables of the class from a static method

Related

Is it possible to modify the value of an attribute sent in argument of a function in Java?

I'm working on a calculator and I search how I can optimize my code.
The thing is that I have much code duplication due to if I'm working on the first number of the calculation or the second. So I'm searching if it is possible to modify the value of an attribute sent in argument of a function ? (I think not because I saw nowhere the answer).
Maybe I'm expressing myself badly so here is a code below to explain what I'm talking about:
public class MyClass
{
private static int number1 = 1;
private static int number2 = 2;
public MyClass()
{
changeValueOf(number1, 3);
}
private static void changeValueOf(int number, int value)
{
//Change here the value of the correct field
}
}
First of all, you can modify static variables inside the method:
private static void changeValueOf(int value)
{
number1 = value;
}
But I guess that is not what you a looking for :)
In Java (and in most other languages) primitive data type (int, short, long, etc) passed by value, e.g. the copy of value passes to the method (function).
And reference types (objects, e.g. created with new operator) passed by reference. So, when you modigy the value of reference type (object) you can see the changes in the outer scopes (for example, in method caller).
So, the answer is no - you cannot change the value of int so that the outer scope would see the updated value.
Howewer, you could wrap your int values with some object - and it change the value inside of it:
public class Example {
public static void main(String[] args) {
Example app = new Example();
// Could be static as well
Holder val1 = new Holder(1);
Holder val2 = new Holder(2);
app.changeValue(val1, 7);
System.out.println(val1.value); // 7
}
public void changeValue(Holder holder, int newValue) {
holder.value = newValue;
}
static class Holder {
int value;
Holder(int value) {
this.value = value;
}
}
}
Also, you could create an array with 2 values and update them inside the method, but it's not very good approach IMO
And finally, you could just return updated value and assign it to your variables:
public class Example {
private static int number1 = 2;
private static int number2 = 3;
public static void main(String[] args) {
Example app = new Example();
number1 = app.mul(number1, 7);
number2 = app.mul(number2, 7);
System.out.println(number1); // 14
System.out.println(number2); // 21
}
public int mul(int a, int b) {
return a * b;
}
}
One possibility is to use an array to store your variables, instead of separate variables with numbers affixed. Then you would write number[1] instead of number1 for example. You can pass the array index number around to indicate which variable you are referring to.
public class MyClass
{
private static int[] variables = {1, 2};
public MyClass()
{
// change value of first variable
changeValueOf(0, 3);
// now variable[0] = 3
}
private static void changeValueOf(int number, int value)
{
variables[number] = value;
}
}

Calling methods on objects Java

I'm taking an introduction to java programming course at university and have an exam next week. I'm going through past exam papers am sort of stuck on this question:
Consider the following class X: class X { private boolean a; private int b; ... }
(i) Write a constructor for this class. [2 marks]
(ii) Show how to create an object of this class. [2 marks]
(iii) Add a method out, which returns b if a is true, and -b otherwise. This method must be usable for any client of
this class. [2 marks]
I've included my code below, but what i'm stuck on is in the final part to this question. How does one call a method on a new object (as we haven't been taught that in class)? Or, does the question imply that the method has to be usable with any object, not just the created object?
Sorry for my awful code and dumb question, i'm really struggling with Java.
public class X {
private boolean a;
private int b;
X(final boolean i, final int j) {
a = i;
b = j;
}
static int Out(boolean a, int b) {
if (a == true) {
return b;
}
return -b;
}
public static void main(String[] args) {;
X object1 = new X(true, 5);
System.out.println(Out(object1));
}
}
You're very close to the solution. Simply make a method like this:
public int out() {
if (a) {
return b;
} else {
return -b;
}
}
Then you can call it in your main method like this:
X object1 = new X(true, 5);
System.out.println(object1.out());
NB: remove the semicolon at the end of public static void main(String[] args) {;
I think you were meant to create a non-static method named out, which can be called by the client of the class (any place where you create a new object of type X) using the dot notation
public int out() {
if(a)
return b;
else
return -b;
}
public static void main(String[] args) {
X object1 = new X(true, 5);
int result = object1.out();
System.out.println(result);
}

Setting variable values to be based on other variables

Say we have variables int a = 0; and int c;.
Is it possible to make it so that c is always equal to something like a + 1 without having to redundantly retype c = a + 1 over and over again
Thanks!
No, it is not possible to make one variable track another variable. Usually, this is not desirable either: when a value of one variable is tied to the value of another variable, you should store only one of them, and make the other one a computed property:
int getC() { return a+1; }
A less abstract example is a connected pair of age and date of birth. Rather than storing both of them, one should store date of birth alone, and make a getter method for computing the current age dynamically.
Since you have 2 variables tied in a specific way, consider using custom object to wrap a and c values. Then you can control the object state inside the class logic. You can do something like this:
public class ValuePair {
private final int a;
private final int c;
public ValuePair(int a) {
this.a = a;
this.c = a + 1;
}
public int getA() {
return a;
}
public int getC() {
return c;
}
}
Firstly, The answer is no, you can't do it directly in Java, but you can redesign your int class, There is an example:
public class Test {
public static void main(String[] args) throws IOException {
MyInt myInt1 = new MyInt(1);
KeepIncrementOneInt myInt2 = new KeepIncrementOneInt(myInt1);
System.out.println(myInt2.getI());
myInt1.setI(2);
System.out.println(myInt1.getI());
System.out.println(myInt2.getI());
}
}
class MyInt { //your own int class for keep track of the newest value
private int i = 0;
MyInt(int i) {
this.i = i;
}
public int getI() {
return this.i;
}
public void setI(int i) {
this.i = i;
}
}
class KeepIncrementOneInt { //with MyInt Class to get the newest value
private final MyInt myInt;
KeepIncrementOneInt(MyInt myInt) {
this.myInt = myInt;
}
public int getI() {
return this.myInt.getI() + 1; //get the newest value and increment one.
}
}
Create your own Int class, because we need a reference type to keep track of the newest the value a. like the MutableInt in apache commons.
Create a always increment 1 class with your own Int class as a member.
In getI method, it's always from the reference Int class get the newest value a.

why i canĀ“t acces to makeRange method

I just started with java and I create a class Range() inside my superclass with a method inside makeRange but when I tried to access to that method throws an error. Whats wrong here?
Here is my code...
public class iAmRichard {
class Range{
int[] makeRange(int upper, int lower){
int[] ary = new int[(upper - lower)+1];
for(int i = 0; i > ary.length; i++ ){
ary[i] = lower++;
}
return ary;
}
}
public static void main(String[] args) {
int foo[];
Range fui = new Range();
foo = Range.(here do not apear makeRange method)
You're creating an inner class here called Range. I don't believe that's what you intended to do, but I'll answer it as stated.
You're referring to this class in a static context, and the inner class can't be referenced with a static context. To address that, you need to make the change to Range: make it static.
public class iAmRichard {
static class Range {
}
}
Further, you're already getting an instance of Range, so all you need to do is use it.
foo = fui.makeRange(1, 10);
If you elected to only create a class called Range, you wouldn't have to deal with any inner classes at all, which I think would be the cleaner approach here.
public class Range {
int[] makeRange(int upper, int lower) {
int[] ary = new int[(upper - lower) + 1];
for (int i = 0; i > ary.length; i++) {
ary[i] = lower++;
}
return ary;
}
public static void main(String[] args) {
int foo[];
Range fui = new Range();
foo = fui.makeRange(1, 10);
}
}
To access a method without creating an instance you have to declare it static. In your case you have also to declare the class Range as static.
Or you can just use the instance you already have with a few changes:
iAmRichard richard=new iAmRichard();
Range fui=richard.new Range();
foo = fui.makeRange(...);
Note tha you need an instance of iAmRichard to create a Range.
Since the call is made from a static block in a static way(No instance is used for calling makeRange method) we need to have the called method to be either static or we need the object of the class to call instance methods.
statically you can use this example to access your method. Here is a link for more information on static methods.
public class IAmRichard {
public static void main(String[] args) {
int foo[];
foo = Range.makeRange(10,1);
}
static class Range{
static int[] makeRange(int upper, int lower){
int[] ary = new int[(upper - lower)+1];
for(int i = 0; i > ary.length; i++ ){
ary[i] = lower++;
}
return ary;
}
}
}

non-static method compute(int) cannot be referenced from a static context

The code given below is giving the following error:- non-static method compute(int) cannot be referenced from a static context
If i cannot create a method inside main(), what should i do.
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Scanner key = new Scanner(System.in);
int t = key.nextInt();
for(int i=0;i<t;i++){
int a = key.nextInt();
int b = key.nextInt();
a=compute(a);
b=compute(b);
System.out.println(a+b);
}
}
int compute(int a){
int basea=0, digit;
int temp=a;
while(temp>0){
digit = temp%10;
temp/=10;
if(digit>(basea-1))basea=digit+1;
}
temp=a;
a=0;
int count=0;
while(temp>0){
digit = temp%10;
temp/=10;
a+=digit*Math.pow(basea,count);
count++;
}
return a;
}
You have two options:
Declare compute() static:
static int compute(int a){
Create an instance of IdeOne and call compute() via that reference:
IdeOne ideOne = new IdeOne();
a = ideOne.compute(a);
I think it would be a good idea to read through the Java tutorials on classes and objects.
You're trying to call a non-static method (which is compute) from a static method (the main).
Change int compute(int a){ with static int compute(int a){
In your case make method compute static. Otherwise create an Ideone object and call your method on it.
You can not access non-static method from static method.
Method you are trying access is instance level method, you can not access instance method/variable without class instance.
You can't access something that doesn't exist. By default non-static method doesn't exist yet, until you create object of that class in which method exist. A static method always exists.
You can access your method by following way :
1. Make your compute() method static
int compute(int a){
///rest of your code
}
2. Create instance of your class Ideone and access method by class object.
IdeOne obj = new IdeOne();
obj.compute(a);
obj.compute(b);
The answers given here are mainly to make the method static, which is fine for a program this size. However, as projects get bigger not everything will be in your main anymore, and thus you get this static/non-static issue on a larger scale as your other classes won't be static.
The solution then becomes to make a class for your Main, as such:
public class Main {
public static void main( String[] args ) {
Ideone ideone = new Ideone();
Then another file which houses your class Ideone:
public class Ideone {
Scanner key;
public Ideone() {
key = new Scanner(System.in);
int t = key.nextInt();
for(int i=0;i<t;i++){
int a = key.nextInt();
int b = key.nextInt();
a=compute(a);
b=compute(b);
System.out.println(a+b);
} // end constructor
int compute(int a){
int basea=0, digit;
int temp=a;
while(temp>0){
digit = temp%10;
temp/=10;
if(digit>(basea-1))basea=digit+1;
}
temp=a;
a=0;
int count=0;
while(temp>0){
digit = temp%10;
temp/=10;
a+=digit*Math.pow(basea,count);
count++;
}
return a;
} // end compute
} // end class
As for your main file. What I do will work, but better practice is to follow the code example given here:
http://docs.oracle.com/javase/tutorial/uiswing/painting/step1.html
Applying this practice will ensure that you do not have static/non-static issues anywhere in your project, as the only thing that is static is the initialization of your actual code, which then handles all codes / further initilization of other classes (which is all non-static)

Categories