Java String function can not be called because it's not static - java

Let me explain further. I have a String function (called stringReversal) that returns a reversed string, it has no errors in the function. But, when I try to print using System.out.println() from the main function, it gives me the error "Can not make a static reference to the non static method stringReversal (string s) from the type StringReverse".
I tried giving my stringReversal a static modifier, but after doing so, it gave me run time errors.
Here's what my code looks like:
public class StringReverse {
public String stringReversal(String s){
if(s == null){
return null;
}
else if(s.length()% 2 == 0){
int size = s.length();
for(int i =0; i<s.length(); i++){
s.replace(s.charAt(i), s.charAt(size));
size--;
if(i == (s.length()/2) || size==0)
break;
}
}
else{
for(int i =0; i<s.length(); i++){
int size = s.length();
s.replace(s.charAt(i), s.charAt(size));
size--;
if(i == ((s.length()/2) +1) || size==0 )
break;
}
}
return s;
}
public static void main(String[] args) {
String str = "Hello";
String rev = stringReversal(str);
System.out.println();
}
}

You have to instantiate your class to call object members, or you need to make your function static, indicating it's not part of object oriented paradigm
In your case you can do
StringReverse sr = new StringReverse();
String rev = sr.stringReversal("hello");
or declare your method differently
public static String stringReversal(String s)
In fact the class name StringReverse itself does not sound like some kind of object, so the second way is preferred impo
The deeper problem you have is the confusion on how Java handle OO and entrance function in general. Java is primarily an OO language so most of the time everything shall be an object or a member of a object. But when you telling the VM to run some java code, there got to be a place to start, which is the main method. There has to be one main method and it must be under some class, but it really has nothing to do with the class that contains it. Within the main method, you either start your OO life by instantiating objects and invoking their members (method 1) or stay in the spaghetti world for a bit longer, by calling other static members as procedures (method 2).

You have two options:
Keep the method non static and then create an instance of your class to call the method:
public static void main(String[] args) {
String str = "Hello";
StringReverse sr = new StringReverse(); // instance of class
String rev = sr.stringReversal(str);
System.out.println(); // just prints a blank line lol...
}
Make the method static (you should do this):
public static String stringReversal(String s) {
// ...
}
public static void main(String[] args) {
String str = "Hello";
String rev = stringReversal(str);
System.out.println(); // just prints a blank line lol...
}
Either way, you have to fix your "run time errors". You can't get around that. If your method doesn't work, keeping it not static won't make it work either.
By the way, I think you meant to do System.out.println(rev); instead of System.out.println();
For the record, here is how to easily reverse a string (both methods work):
public static String stringReversal(String s) {
StringBuffer reverseString = new StringBuffer();
// reverse the string
for (int i = s.length() - 1; i > -1; i--) {
reverseString.append(s.charAt(i));
}
return reverseString.toString();
}
/* using the reverse() method in the StringBuffer class
instead of reversing the string through iterations */
public static String stringReversal2(String s) {
return new StringBuffer(s).reverse().toString();
}

This is happening because your Main method is static, but the class that it's in is not. In order to call a non-static method, you need to create an instance of the class. Alternatively, the method can be made static, but in order to refer to it you need to include the class name in your call (as if to use the class itself like an object containing the method - see below).
There are three solutions to this problem:
Make an instance of the class and call the method from your object (recommended).
make the method static and use StringReverse.stringReversal().
Make the class AND the method static.

Related

Eclipse JAVA String reverse - reversing 1 word which is pre-declared [duplicate]

This question already has answers here:
Reverse a string in Java
(36 answers)
Closed 5 years ago.
Like to know how to reverse a string value (1 word) which is pre-declared in the program. I mean not using user input or scanner.
Like to reverse a word "TRAIN" which is pre-declared in the program.
Have tried the below program but no results and no error also.
// QUERY PROGRAM NOT RUNNING - NO RESULT, NO ERROR.
// STRING REVERSE PROGRAM USING ARRAY
package abnpackage;
class Play {
void REVERSE (){
String [] INPUT_WORD = {"T","R","A","I","N"};
int Q;
for(Q=INPUT_WORD.length-1; Q>=0; Q=Q--);
System.out.print ("REVERSE VALUE" + INPUT_WORD[Q]);
}
public static void main(String[]args){
Play PL = new Play();
PL.REVERSE();
}
}
Problem in Q=Q-- and ; symbol after for cylce. Try this:
class Play{
void REVERSE (){
String [] INPUT_WORD = {"T","R","A","I","N"};
int Q;
for(Q=INPUT_WORD.length-1; Q>=0; Q--) {
System.out.print(INPUT_WORD[Q]);
}
}
public static void main(String[]args){
Play PL = new Play();
PL.REVERSE();
}
}
I'd like to offer a few suggestions.
Indent your code. It not only makes it easier for you to follow, but makes it easier for others to read your code.
Naming conventions. Use Title case for classes, camelCase for both variables and methods, and UPPER_CASE for constants.
Strings and characters. A String can be decomposed into an array of characters with the built-in method, String.toCharArray(). A character array is mutable, so is often used as an intermediate structure when converting a String from one state to another for tasks like ciphers or interview problems.
Encapsulation. If you can make your methods use only what is submitted to them through their method signature, and only output their return value, it's usually best. Prefer passing values over referencing constants in your utility methods to make them easier to follow.
package abnpackage;
class Play {
private static final String INPUT_WORD = "TRAIN";
private String reverse(String word) {
char[] letters=word.toCharArray();
StringBuilder sb=new StringBuilder();
for (int q=letters.length-1; q>=0; q--) {
sb.append(letters[q]);
}
return sb.toString();
}
public static void main(String[]args) {
Play play = new Play();
System.out.println("REVERSE VALUE: " + play.reverse(INPUT_WORD));
}
}
class Play {
void REVERSE() {
String[] INPUT_WORD = {"T", "R", "A", "I", "N"};
String[] OUTPUT_WORD =new String[INPUT_WORD.length];
int length = INPUT_WORD.length;
int i = 0;
while(--length>=0){
OUTPUT_WORD[i++] = INPUT_WORD[length];
}
System.out.println(Arrays.toString(OUTPUT_WORD));
}
public static void main(String[] args) {
Play PL = new Play();
PL.REVERSE();
}
}
Your code is entering an endless loop because of the assignment "Q=Q--"
for(Q=INPUT_WORD.length-1; Q>=0; Q=Q--);
It should instead be
Q--
without a semicolon at the end.
If the code runs successfully, it will print the words "REVERSE VALUE" repeatedly prior to printing each character in reverse.
System.out.print ("REVERSE VALUE" + INPUT_WORD[Q]);
So you will want to keep the text in reverse prior to printing the whole statement at the end of the execution of the for loop.
What is the reason to use array of String instead of just String? Since it's not mentioned as a requirement, I'm suggesting the following as an alternative solution:
public class Play {
static void reverse(){
String inputWord = "TRAIN";
char[] toStrArray = inputWord.toCharArray();
char[] revisedInput = new char[inputWord.length()];
int i = 0;
for(int q=toStrArray.length-1; q>=0; q--){
revisedInput[i]=toStrArray[q];
i++;
}
System.out.print ("REVERSE VALUE: " + new String(revisedInput));
}
public static void main(String[]args){
//Play PL = new Play();
//PL.REVERSE();
reverse();
}
}
Note: You can declare the method reverse as a static method. By doing this you don't have to create an object before calling it. Hope this helps.

Calling non-static method (in a different class) from static

I've done some looking around on here for a solution, but I can't find one. I tried these ones and many others, and I run into the same issue.
I am trying to make a simple text game, and I run into the issue where I have a main class, and a class called "gameboard" that I have as an array defined like this:
static GameBoard[] gameboard = new GameBoard[9];
Now, this works fine until I try to change the characteristics of a single one of these array objects. I will do:
gameboard[input].setState(2);
and the specific instance of gameboard that should change will not be the only one: all of them change when I do this. It's weird. Only gameboard[**input**] should change, not all 9 of the gameboard instances. EVERY variable and method I have is "static", but because of the main method (public static void main...), everything seems to have to be static. How do I get rid of all this static?
GameBoard Class
package com.name.tictactoe;
public class GameBoard {
char[] States = {'N','X','O'};
char state;
public void setState(int s){
state = States[s];
}
public char getState(){
return state;
}
}
Main class (called Game)
package com.name.tictactoe;
import java.util.Scanner;
public class Game {
static boolean turn, win;
static GameBoard[] gameboard;
static Scanner kb = new Scanner(System.in);
static int input;
public static void main(String[] args){
gameboard = new GameBoard[9];
reset();
displayStates();
askTurn();
displayStates();
askTurn();
}
public static void askTurn() {
System.out.println();
System.out.println();
System.out.println("Where do you want to go? Use the numbers shown, where the first segment is the top and the last is the bottom - left to right.");
input = kb.nextInt();
if(input > 8){
System.out.println("Input out of bounds. Game over by default.");
try {
Thread.sleep(1000000000);} catch (InterruptedException e) {e.printStackTrace();}
}
gameboard[input].setState(2);
}
public static void reset(){
for(int i = 0; i < 9; i++){
gameboard[i].setState(0);
}
}
public static void displayStates(){
for(int i = 0; i < 9; i++){
System.out.print(gameboard[i].getState() + " ");
if(i ==2 || i ==5){
System.out.print(" II ");
}
}
System.out.println();
for(int i = 0; i < 9; i++){
System.out.print(i + " ");
if(i ==2 || i ==5){
System.out.print(" II ");
}
}
System.out.println();
}
}
UPDATE: The current answers don't work. Although Eclipse doesn't realize this, making GameBoard non-static causes null pointer exceptions when any method in it is referenced.
A static variable belongs to the class, not the object, so of course all of your GameBoards are being affected!
Just because you're in a static method doesn't mean you can't manipulate instance variables. First, make everything in your GameBoard class non-static (unless you really do need some of the values shared across all instances). This includes your instance variables and your getter/setter methods.
If your program works exclusively from the main method, then keep your GameBoard[] object static. Then, when you make that method call:
gameboard[input].setState(2);
This will change only the state of the GameBoard at index input.
Edit:
To instantiate your GameBoard[] with basic GameBoard objects inside of it, you can do this at the beginning of your main method:
for(int x=0; x<gameboard.length; x++) {
gameboard[x] = new GameBoard(); //Assuming you want to use the default constructor
}
The other objects in your array should not change. Can you add some more code for more context?
As far as I can understand you, you are doing something like:
public class Main {
public static String[] strings = new String[2];
public static void main(String[] args) {
strings[0] = "test";
System.out.println(strings[1]);
}
}
In my example output is "null" as expected.
How do I get rid of all this static?
Just create instances of your objects in the main function.
GameBoard[] gameboard = new GameBoard[9];
For what you describe to happen all the elements of the gameboard array must be set to the same object (nothing to do with the array being static), check your code where you populate the gameBoard array with new instances of the GameBoard class for a bug that could cause the same instance to be written to all elements (or post that code here so people can see the problem).

Making a program into two different classes

So I had to write a code that takes a word and reverse it I got it to work but for my homework I had to make it into two classes a tester class and a main class how do I do that?
public static void main(String args[])
{
String original = "";
String reverse = "";
Scanner in = new Scanner(System.in);
System.out.println("Enter a string to reverse");
original = in.nextLine();
int length = original.length();
for ( int i = length - 1 ; i >= 0 ; i-- )
{
reverse = reverse + original.charAt(i);
}
System.out.println("Reverse of entered string is: "+reverse);
}
You create two classes. You can even put a main method in both of them.
public class Homework {
public static void main(String[] args) {
// Code here to prompt user for string and to print reversed string
}
static String reverse(String input) {
// Code here to do the actual reverse logic, returning reversed string
}
}
public class HomeworkTest {
public static void main(String[] args) {
test("Hello", "olleH");
test("This is a test", "tset a si sihT");
}
private static void test(String input, String expected) {
String rev = Homework.reverse(input);
System.out.println(input + ": " + rev);
if (! expected.equals(rev))
System.out.println(" ** NOT AS EXPECTED: " + expected);
}
}
You can now run the Homework for manual testing, or the HomeworkTest class for automatic testing.
You could get the original String in the Main-class and hand it to the second class to execute the for-loop. The second class then returns the reversed String so that the Main-Class can print it out.
The second class could contain a static method which reverses the String (executes the for-loop) or you can create an object of the second class and and this Object the original String to reverse.
There are several ways to do this. Most trivially, you could make a static function in a Test class, like so:
class Test
{
public static void runTest(String args[])
{
//same as your above program
}
}
But that is probably not what your teacher wants. Instead, you could make a Test class that reverses a set of strings.
class Test
{
public static void runTests()
{
//iterate through a list of hard-coded strings to test
}
}
You would then make a separate function in a Reverser class and the Test.runTests() function would test the Reverser class.
However, there are standardized ways of doing this. One common way is called JUnit. If you are using Eclipse, try this page for instructions.
The simplest way is to
Divide your code into a function public String reverse(String input)
Create new Tester class
Add test method in tester class public void test()
Prepare assertions to test your function assert reverse("ola").equals("alo") : "First assertion failed"
In main function run new Tester().test();
To make assertions working you have to run jvm with -ea option

I want to check the number of characters in a String method

I want to check that a certain number of characters in a method that inputs and returns string
public static String watsonCrick(String dna){
dna = "ATA";
int length = dna.length();
char firstCharacter = dna.charAt(0);
char secondCharacter = dnaSequence.charAt(1);
char thirdCharacer = dna.charAt(2);
}
This is my code so far but I dont know what to put as my return and I don't know how to call the method from my main method? All I need is to make sure the string "dna" has three characters in it.
The method doesn't return anything as of yet, I really just want to make sure I'm on the right track and this is how I have to restrict the number of characters in my string.
EDIT: Sorry to add one more thing but if I wanted to add a condition to the method, like let's say I already made a boolean method beforehand and wanted to check if the char firstCharacter was true according to the method how would I add it?
I don't know how to call the method from my main method?
Like this:
public static void main(String[] args) {
watsonCrick("ATA");
}
or if the watsonCrick method is in a different class, like this:
public static void main(String[] args) {
OtherClass.watsonCrick("ATA");
}
All I need is to make sure the string "dna" has three characters in it.
You can do this by putting this at the beginning of the watsonCrick method:
if (dna.length() != 3) { throw new IllegalArgumentException(); }
Assing dna variable in Main method and then write just methodName(Parameters) for calling the method in Main. i.e
String dna;
public static void main(String[] args) {
dna = "ATA";
watsonCrick(dna);
}
And if you need to make sure the string has three characters, use this;
public static String watsonCrick(String dna){
int length = dna.length();
if(length == 3) {
return "true";
}
return "false";
}
If you want you can change the return type to Boolen. (True or False)

How is it that I can modify a final variable in Java when calling a method recursively

public class MyClass {
public void display(String s) {
final char c = s.charAt(0);
System.out.println(c);
if (s.length() > 1) {
display(s.substring(1));
}
}
public static void main(String[] args) {
MyClass mC = new MyClass();
mC.display("SampleString");
}
}
When I execute the following code how is that I am able to modify the value of final variable c when calling display recursively. Isnt final supposed to restrict the user from doing that
You are not modifying the variable, each call of this method gets a new instance of the variable. If you only want one instance you can move the declaration into the class body and declare it "static".
Variable c is scoped inside its enclosing method. That's why when you call it recursively, each time it is different variable c.
You are not modifying a final variable, you are creating a new stack frame and that creates a new variable c for your method display. Also, your method takes one char from the String each time, and you get a new String. So,
public void display(final String s) { // <-- you *could* make `s` final
if (s == null || s.length() < 1) return;
final char c = s.charAt(0);
System.out.print(c); // <-- why put each char on a new line?
if (s.length() > 1) {
display(s.substring(1)); // <-- recurse.
} else {
System.out.println(); // <-- last char. new line.
}
}

Categories

Resources