I have read that a static method can't call a no-static method, but this compile, the main(static) method call maybeNew(no-static) method, can you give me a clue?
public class Mix4 {
int counter = 0;
public static void main(String[] args) {
int count = 0;
Mix4[] m4a = new Mix4[20];
int x = 0;
while (x<9) {
m4a[x] = new Mix4();
m4a[x].counter = m4a[x].counter + 1;
count = count + 1;
count = count + m4a[x].maybeNew(x);
x = x + 1;
}
System.out.println(count + " " + m4a[1].counter);
}
public int maybeNew(int index) {
if (index<5) {
Mix4 m4 = new Mix4();
m4.counter = m4.counter + 1;
return 1;
}
return 0;
}
}
You can not call a non-static method directly from a static method but you can always call a non-static method from a static method using an object of the class.
public class Main {
public static void main(String[] args) {
// sayHello(); // Compilation error as you are calling the non-static method directly from a static method
Main main = new Main();
main.sayHello();// OK as you are calling the non-static method from a static method using the object of the class
}
void sayHello() {
System.out.println("Hello");
}
}
Related
I am trying to use a method to print a random number multiple times using increments. The problem is I don't seem to understand methods very well. I have no problem doing it otherwise but when I try to do it by calling a method I can't get any return and my console just remains blank. Here is what I have so far:
package WayBack;
import java.util.Random;
public class Review {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
{
method1();
}
public String method1()
{
String rv = "";
for(int i = 0; i <= 4; i++)
{
Random r = new Random();
int number = r.nextInt((100) - 0) * 100;
System.out.println("your number is " + number);
}
return rv;
}
}
Any help would be much appreciated
Thank You
You need to invoke the method1 function in main. But your method1 function is an instance method. So you should new an Instance of the Review class, and then invoke the method1 function.
public static void main(String[] args) {
// TODO Auto-generated method stub
Review instance = new Review();
instance.method1();
}
Or, You can declare the method1 as static so that you can call it directly in the main method.
public static void main(String[] args) {
// TODO Auto-generated method stub
method1();
}
public static String method1()
{
String rv = "";
for(int i = 0; i <= 4; i++)
{
Random r = new Random();
int number = r.nextInt((100) - 0) * 100;
System.out.println("your number is " + number);
}
return rv;
}
An other way, you can invoke the method1 in the constructor of the Review class. And If you create an instance of a class, the methods in the constructor of the class are automatically called. In this way, you don't have necessary to invoke your method in the main.
public static void main(String[] args) {
// TODO Auto-generated method stub
Review instance = new Review(); // it will call the method1 automatically
}
public Review() {
// invoke your method
method1();
}
In your code, you are not calling the method method1. It is not wrapped in Main, instead it is wrapped in a set of floating curly braces.
package WayBack;
import java.util.Random;
public class Review {
public static void main(String[] args) {
method1(); // put it here
}
// This block is not executed
{
method1();
}
public String method1()
{
String rv = "";
for(int i = 0; i <= 4; i++)
{
Random r = new Random();
int number = r.nextInt((100) - 0) * 100;
System.out.println("your number is " + number);
} return rv;
}
}
As everyone is pointing out, you need to include method1() inside your main.
The reason for this is because Java starts all programs in public static void main(String[] args) from here it reads one line at a time inside the block of code. A block of code is defined as what is in the '{' and '}', often called braces.
Because the main method is ALWAYS static, and you cannot reference non-static things inside a static method, you will either need to change your method1 to also be static or create an object that can reference the method. You will learn about this later on.
For now,
public static void main(String[] args) {
method1();
}
public static String method1() {
String rv = "";
Random r = new Random(); //this 'r' object only needs to be created once.
for(int i = 0; i <= 4; i++)
{
int number = r.nextInt(100) * 100; // you were subtracting 0 for no reason?
System.out.println("your number is " + number);
rv = rv + number + ", "; //rv is empty in your example, this will fill it with the 5 numbers generated. (It's not perfect)
}
return rv;
}
Your rv variable return an empty value.
You can create a class(MyClass) where in future you can Add other methods:
For example you can do:
package WayBack;
import java.util.Random;
public class Review {
public static void main(String[] args) {
// TODO Auto-generated method stub
public MyClass work=new MyClass();
work.method1();
}
}
//---create an other file and write this one
Public Class MyClass{
private String rv;
private int number;
private Random r;
//constructor
public MyClass(){
this.number=0;
this.rv="";
this. r= new Random();
}
public String method1() {
for(int i = 0; i <= 4; i++) {
number = r.nextInt((100) - 0) * 100;
System.out.println("your number is "+number);
rv=rv+number+","; }
return rv; }
}//end MyClass
Since 'method1' is called in a block, this will execute at the time when you create the object.
{
method1();
}
You only have to create the object in the main method. No need to make method static.
Try this,
public static void main(String[] args) {
// TODO Auto-generated method stub
Review review = new Review();
}
package basicprograms;
public class Progrm {
public long[] ph;
public Progrm(long[] ph){
this.ph=ph;
}
}
The main method:
package basicprograms;
import java.util.ArrayList;
public class UseProgrm {
public static void main(String[] args) {
ArrayList<Progrm> ar = new ArrayList<>();
Progrm p1 = new Progrm(new long[] { 942758427l, 4298578432l, 3425962l });
Progrm p2 = new Progrm(new long[] { 942758427l, 4298578432l, 3425962l });
Progrm p3 = new Progrm(new long[] { 942758427l, 4298578432l, 3425962l });
ar.add(p1);
ar.add(p2);
ar.add(p3);
for (int i = 0; i < ar.size(); i++) {
System.out.println(ar.get(i));
}
}
}
By default, all classes in Java inherit from the Object class. In this case what you are actually printing is Progrm::toString method that is inherited for the Object class and by default is returning the hash. If you would like to print the content of the array(public member ph of the Progrm class) then you should override the toString of Progrm as follows:
public class Progrm {
public long[] ph;
public Progrm(long[] ph) {
this.ph=ph;
}
#Override
public String toString() {
return "Progrm{" +
"ph=" + Arrays.toString(ph) +
'}';
}
}
and the output will be:
Progrm{ph=[942758427, 4298578432, 3425962]}
Progrm{ph=[942758427, 4298578432, 3425962]}
Progrm{ph=[942758427, 4298578432, 3425962]}
For more info on Object::toString, you can refer to :
Why does the default Object.toString() include the hashcode?
You have to override the toString() method in your Program class
now, the System.out.println statements are calling the default implementation of the Object class.
Add this to your Program class:
public String toString() {
StringBuilder b = new StringBuilder("");
for ( long p : ph) {
b.append("Value: " + p + ", ");
}
return b.toString();
}
Afterwards, you can modify it to fit your needs.
Try this:
for (int i = 0; i < ar.size(); i++) {
for(int j = 0; j < ar.get(i).ph.length; j++)
System.out.println(ar.get(i).ph[j]);
}
I am trying to understand how reflection works, i cant able to figure out the problem. In the second for loop method.length is not fetching method from another program.
Following is the code:
public class DriverScript
{
public static ActionKeywords actionKeywords;
public static String sActionKeyword;
public static Method method[];
public DriverScript() throws NoSuchMethodException, SecurityException
{
actionKeywords = new ActionKeywords();
method = actionKeywords.getClass().getMethods();
}
public static void main(String[] args) throws Exception
{
System.out.println(method);
String sPath = "C:\\Users\\mag6\\Desktop\\toolsqa.xlsx";
ExcelUtils.setExcelFile(sPath, "Test Steps");
for (int iRow = 1; iRow <= 9; iRow++)
{
sActionKeyword = ExcelUtils.getCellData(iRow, 3);
execute_Actions();
}
}
private static void execute_Actions() throws Exception
{
for (int i = 0; i < 11; i++)
{
if (method[i].getName().equals(sActionKeyword))
{
method[i].invoke(actionKeywords);
break;
}
}
}
}
public class Test2 {
//Reflection in Keyword driven Framework
/**
* #authors Venkadesh,Selvakumar work name : Test
**/
static Class Class1 = ActionKeywords.class;
static ActionKeywords Keywords = new ActionKeywords();
public static void main(String[] args) throws Exception {
String sPath = "C:\\Users\\mag6\\Desktop\\toolsqa.xlsx";
ExcelUtils.setExcelFile(sPath, "Test Steps");
Method[] methods = Class1.getDeclaredMethods();
for (int i = 1; i <= 9; i++) {
// This to get the value of column Action Keyword from the excel
String sActionKeyword = ExcelUtils.getCellData(i, 3);
for (int j = 1; j <= 9; j++) {
if (methods[j].getName().equals(sActionKeyword)) {
try {
methods[j].invoke(Keywords);
} catch (Exception e) {
}
System.out.println(methods[j]);
}
}
}
}
}
try with this it works
You are not calling the constructor for DriverScript so the fields are not initialized.
Try changing your methods from static to non-static and fix from there.
Replace
public static Method method[];
with
public static Method method[]= ActionKeywords.class.getDeclaredMethods();
Could some one tell me how can i get variable inside methods and the reverse.
Something like:
i want to use variable y inside that method func, and get that x from that method func and use it inside main.
class test{
int y = 4;
void func(){
int x = 3;
}
public static void main(String[] args)
{
// take x inside main
}}
You can always use class variable inside methods. To use x of func() inside main() method, you can return it from func() or save it into some class variable
class TestClass {
int y = 4;
int x = 0;
//func returning x
int func1() {
int x = y;
return x;
}
//func storing it to class variable
void func2() {
this.x = 3;
}
public static void main(String[] args) {
TestClass t = new TestClass();
int xOfFunc = t.func1();
t.func2();
System.out.println("x Of Func :: " + xOfFunc + "\n class variable x :: " + t.x);
}
}
output :
x Of Func :: 4
class variable x :: 3
class test{
int y = 4;
int func(){
int x = 3;
return x;
}
public static void main(String[] args)
{
test obj = new test();
int x = obj.func();
}
}
or you can make func() method static and you will be able to call this method without creating an object of class:
class test{
int y = 4;
static int func(){
int x = 3;
return x;
}
public static void main(String[] args)
{
int x = func();
}
}
Try something like this:
class Main {
public int y= 4;
int func(){
return 4;
}
public static void main(String... args){
Main m = new Main();
int x = m.func();
int y = m.y;
}
}
class test{
int y = 4;
int x;
void func(){
int x = 3;
this.x = 3; //make it usable from the class
}
}
y should be accessible inside the function. If the function uses a variable y by itself you can use this.y to access the variable.
Make it static like this allows you to access it everywhere by calling test.y.
class test{
public static int y = 4;
void func(){
int x = 3;
}
}
Then you can do this in main.
public static void main(String[] args)
{
int value = test.y;
}
In Java, the output of s is 0. I do not understand why and would it be possible to somehow get the correct value of s (1000 here)?
public static void main(String args) {
int s = 0;
List<Integer> list = getList(s);
System.out.println("s = " + s);
}
public static List<Integer> getList(int s) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 1000; i++) {
list.add(i); s++;
}
}
In C# there were out descriptors to indicate that the variable is going to change if I'm not mistaken..
I'm not going to get the list.size() in general!
In Java, all method arguments are passed by value, i.e. copy. So, changes to the copy are not visible to the caller.
To address your second question, you can just use list.size() on the caller side.
I see two ways
1) Make 's' as static variable and move it to class level
2) Create class with getter/setter for list and int and return the object for getList call
public static MyWrapperObj getList(int s) {
......
return wrapperObj
}
class MyWrapperObj
{
private List<Integer>;
private countS;
....
//getter/setters.
}
Java doesn't allow for passing parameters by reference - but you could wrap it in an object like this:
class IntHolder {
private int s;
IntHolder(int s){
this.s = s;
}
public void setS(int s){
this.s = s;
}
public int getS(){
return s;
}
public void increment(){
s++;
}
}
class Test{
public static void main(String[] args) {
IntHolder s = new IntHolder(0);
List<Integer> list = getList(s);
System.out.println("s = " + s.getS());
}
public static List<Integer> getList(IntHolder s) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 1000; i++) {
list.add(i); s.increment();
}
return list;
}
}
In java, arguments passed to methods are passed by value.. you will need to make s a global or instance variable in order to modify it in other methods. This is just the way java works. e.g.
public class Test{
private int s;
public Test(){
s=0;
increment();
//print now will be 1000.
}
private void increment(){
s = 1000;
}
}