Invoke method without instance via constructor in Java - java

I have a great doubt as to what this action is called and how it is administered in memory.
Inside the main() method I make these sentences or instructions.
public static void main(String[] args) {
int i = 0;
int j = new Random().nextInt(100); // As it is called this way of acting or as it is called.
}
I have clear that what it does is directly invoke the Random class constructor method, invoke the nextInt method and generate a random number that is stored inside the int j variable but I don't know how to define this type of action and I don't know if it is correct to do this kind of instructions.
I'm curious to know what this type of action is called.
Thank you for your attention.
P.D : Sorry .. I'm learning

int j = new Random().nextInt(100);
is almost the same as
Random r = new Random();
int j = r.nextInt(100);
i.e. both create an instance (object) of the Random class, and then call a method of that instance.
The difference is that in the first case, you don't keep a reference to the created instance, so you can't access that instance again, and since no reference to that instance exists, it can be immediately garbage collected.
As Andy suggested, you can look at it as if you created an instance of the Random class and assigned it to a variable, called the nextInt() method, and then exited the scope in which that variable was declared:
int j;
{
Random r = new Random();
j = r.nextInt(100);
}
// at this point you have no access to the Random instance

One important note: this code is a bit shorter, and it's OK if you will not need to call nextInt() again. If you will, you better store the instance on Random class in a variable because the process of creating multiple Random objects for multiple int values is TOO heavy.

Well technically there is an instance of the class, since you see the keyword new.
What you see here is called method chaining.
You first call the constructor with new Random() and then chain the nextInt() method to it.
if you are curious how can you call a method without an instance of a class, the simple answer is you need a static class :) a good reference on static classes
But a simple example would be the Math class in java, with it you can do this:
double floor = Math.floor(7.343);
notice how you dont use "new" when invoking Math

Related

Why Must this method be static(Java)?

For some background, I'm currently on chapter 8 in my book, we finished talking about arraylists, arrays, if statements, loops etc. Now this part of the book talks about call by reference,value and some other pretty neat things that seem odd to me at first.I've read What situation to use static and some other SO questions, and learned quite a bit as well.
Consider the following example my book gave (among many examples)
There is another reason why static methods are sometimes necessary. If
a method manipulates a class that you do not own, you cannot add it to
that class. Consider a method that computes the area of a rectangle.
The Rectangle class in the standard library has no such feature, and
we cannot modify that class. A static method solves this problem:
public class Geometry
{
public static double area(Rectangle rect)
{
return rect.getWidth() * rect.getHeight();
}
// More geometry methods can be added here.
}
Now we can tell you why the main method is static. When the program
starts, there aren’t any objects. Therefore, the first method in the
program must be a static method.
Ok, thats pretty cool, up until now I've just been really blindly putting public in front of all my methods, so this is great to know. But the review small problem on the next page caught my attention
The following method computes the average of an array list of numbers:
public static double average(ArrayList<Double> values)
Why must it be a static method?
Here I was like wait a sec. I'm pretty sure I did this without using static before. So I tried doing this again and pretty easily came up with the following
import java.util.ArrayList;
class ArrList
{
private double sum;
public ArrList()
{
sum = 0;
}
public double average(ArrayList <Double> values)
{
for(int i = 0; i < values.size() ; i++)
{
sum+=values.get(i);
}
return sum / values.size();
}
}
public class Average
{
public static void main(String [] args)
{
ArrList arrListObj = new ArrList();
ArrayList<Double> testArrList = new ArrayList<Double>();
testArrList.add(10.0);
testArrList.add(50.0);
testArrList.add(20.0);
testArrList.add(20.0);
System.out.println(arrListObj.average(testArrList));
}
}
TLDR
Why does my book say that public static double average(ArrayList<Double> values) needs to be static?
ATTEMPT AT USING STATIC
public class Average
{
public static void main(String [] args)
{
ArrayList<Double> testArrList = new ArrayList<Double>();
ArrayList<Double> testArrListTwo = new ArrayList<Double>();
testArrList.add(10.0);
testArrList.add(50.0);
testArrList.add(20.0);
testArrList.add(20.0);
testArrListTwo.add(20.0);
testArrListTwo.add(20.0);
testArrListTwo.add(20.0);
System.out.println(ArrList.average(testArrList));
System.out.println(ArrList.average(testArrListTwo)); // we don't get 20, we get 53.3333!
}
}
It doesn't.
The only method which needs to be static is the initial main() method. Anything and everything else is up to you as the programmer to decide what makes sense in your design.
static has nothing to do with public accessors (as you allude to), and it has nothing to do with the technical operation being performed. It has everything to do with the semantics of the operation and the class which holds it.
An instance (non-static) method exists on a particular instance of a class. Semantically it should perform operations related to that specific instance. A static method exists on a class in general and is more conceptual. It doesn't do anything to a particular instance (unless it's provided an instance of something as a method argument of course).
So you really just need to ask yourself about the semantics of the operation. Should you need new instance of an object to perform an operation? Or should the operation be available without an instance? That depends on the operation, on what the objects represent, etc.
If it is not static, then any other class that wants to use this method must first create an instance of this object.
From some other class:
Average.average(new ArrayList<Double>()); // legal only if static
new Average().average(new ArrayList<Double>()); // necessary if not static
// and only makes sense if Average can be instantiated in the first place
It's legal to make it an instance (i.e. not static) variable, but the method is actually harder to understand. If it is static then whoever reads the code knows it does not use any member variables of the class.
// In the class body
int x = 0; // member variable
public static double average() {
x = x + 1; // illegal
}
The less something can do, the easier to understand what it does do.
Static methods like the area, average are usually utility functions. You don't need any object to use an utility function. For example consider Math.pow you don't need to instantiate any object to use the power function, just use Math.pow(10.0, 2.0) to get (10.0)^2
In short :
Static method means class method, that is no instance of that object is needed to invoke.
whereas your average method is an instance method, you need an object to invoke that method.

I need help passing an array and calling basic methods on it

I'm new to programming and java, and I'm trying to write a simple bubble sorting algorithm. I might be in a bit over my head; I'm not too far along in Oracle's java tutorials. The trouble I'm having now isn't with the bubble sorting itself, but in creating the array and printing it before it is sorted.
Here is what I have so far:
public class BubbleSort {
public BubbleSort(int size) {
// creates array
int[] items = new int[size];
}
public void fillArray(int[] a) {
// fill array with random ints
for (int i=0; i<(a.length-1); i++) {
a[i] = java.util.Random.nextInt(50);
}
}
public void printArray(int[] a) {
for (int i=0; i<a.length; i++) {
System.out.print(a[i] + " ");
}
}
public void BubbleSortAlgorithm() {
// bubble sorting algorithm goes here
}
public static void main(String[] args) {
BubbleSort bubbleSort = new BubbleSort(20);
bubbleSort.fillArray(items);
bubbleSort.printArray(items);
// bubbleSort.BubbleSortAlgorithm(items);
// bubbleSort.printArray(items);
}
}
I'm getting 3 compiler errors:
non-static method nextInt(int) cannot be referenced from a static context
Is this because it is called in the main method? How do I get around that?
2.,3. the compiler can't find the symbol, items. Items is an array of ints that is created in the constructor for the class. Do I need to declare it in the main method?
I have a feeling that my class structure is completely off. Again, I'm very new. I'm also new to stackoverflow, so I'm also sorry if this question isn't presented well.
You call:
java.util.Random.nextInt(50);
It's preferred to import classes you're going to use. That would put this block at the top of the file:
import java.util.Random;
And change the existing code to:
Random.nextInt(50);
That fixes the style problem, but you're still going to get the same compiler error.
Static methods are things that belong to a class; they don't need you to create (instantiate) an object of that class before using them. Instead of every instantiation of a class having that method, all instantiated instances of the class share the same static methods and variables.
Specifically, .nextInt() in the Random class is not a static; it's a normal method. So it needs an instantiated Random to work on. Which means you should try:
Random random = new Random();
random.nextInt(50);
After you've instantiated a Random, you can then keep calling nextInt() on it, as many times as you'd like.
One example of static methods that are commonly used are in the Math class.
Math.min(10, 5);
Math.max(100, 100000);
And so on.
The reason Random needs to be instantiated is that it has state. It's not fully random, but pseudo-random, in that it needs a number to start with. If you don't give it a number, it takes the current time. Two Java Random objects initialized at exactly the same moment... will produce the same series of "random" numbers.
This is actually useful; you can give them Random object the number to start with, and you can use this behavior for testing purposes.
Random random = new Random(1);
That's seeding it with the number 1. Which means it'll produce the same random numbers for nextInt() every time you run your code. If you don't give it any number as a seed, it's doing this, instead:
Random random = new Random(System.currentTimeMillis());
But yeah; the problem is that Random.nextInt isn't a static method.
First thing is
NextInt method of non static
So you have to use instance of random class to use it
Second one
Item is local variable so you have to must declare it before use it

Why can't I instantiate outside any method in java?

Please ignore my arrogance......learning java these days, i came across this perfectly same question for my problem : Why can't I instantiate and create Object without main method? (Stack Overflow Error)
Expecting a possible downvote too...but please go through my question once!!!!
Code that i was trying :
public class Arrayprg{
Arrayprg ag = new Arrayprg(); //ignore this for a while and go thru code please
public static void main(String []args){
System.out.println("Hello Array");
new Arrayprg().declarearray();
}
public void declarearray()
{
int[] arr;
arr = new int[11];
new Arrayprg().assignarr(arr);
}
public void assignarr(int arr[])
{
int i;
for(i = 0; i < 11; i++)
{
arr[i] = i;
}
new Arrayprg().printarr(arr);
}
public void printarr(int arr[])
{
int i;
for(i = 0; i < 11; i++)
{
System.out.println(arr[i]);
}
}
}
Thinking logically, going through the code you'll see lots of new arrayprg()....what i thought of was to instantiate outside of methods and calling all methods through it there after, but i guess it is not allowed in java.
Whats causing my Problem
Going by the solution in quoted question, as it explain that below thing happens :
Create new instance of Arrayprg
-> ag = Create new instance of Arrayprg
-> ag = Create new instance of Arrayprg
-> ag = Create new instance of Arrayprg
Explanation given in that question
.....it is initialized whenever an instance of the class is instantiated. This will never terminate until you run out of memory and get the stack overflow. Run it with a debugger for a clearer view.
My Question
so i have Arrayprg ag = new Arrayprg(); in my program which is creating a loop every-time i create an instance but why is this called when i am calling the functions through new Arrayprg().
What i mean is that when i am calling the function through new Arrayprg() inside the methods why is Arrayprg ag = new Arrayprg(); getting called and creating the loop of error for Stackoverflow?????
This will cause a StackOverflowError.
The line you tell us to ignore, interestingly, is the culprit. When you instantiate a new Arrayprg then any object initializers are called, including new Arrayprg() which will then recursively try to keep invoking constructors without end. Remove that line, or put it in a static initializer. Better yet, just don't create that Arrayprg outside the main method as your Arrayprg does not need an instance of Arrayprg itself,
I would be more clear but I don't know what you're trying to achieve.
Solution : Change this line:
Arrayprg = new Arrayprg(); //ignore this for a while and go thru code please
to:
static Arrayprg a = new Arrayprg();
And you will no longer get your infinite recursion problem as now it will only create one instance of it shared between all instances - rather than each instance immediately creating a new one.
The Explanation
As part of constructing an Object in Java all member variable initializers, initializer code blocks, etc are all called as well as the constructor itself.
So in order to create a new Arrayprg one of the things it does is look for member variables that need initializing and initialize them.
In this case it finds Arrayprg a = new Arrayprg();, so in order to initalise the field a, it tries to create a new Arrayprg().
But that new Arrayprg() goes through the exact same process again, and again, and again, etc.
There are a number of ways to fix this - including:
Pass in the Arrayprg as a parameter to the constructor - so a new one doesn't need to be created.
Make the Arrayprg static - so only a single one needs to be created once rather than creating a new one each time
Lazy initaliziation on the Arrayprg so that you only create it the first time you try and access it rather than when the parent Arrayprg is created.
Why it doesn't happen in a method call:
The important thing that causes the recursion here is that the call happen during the creation of a new object. If trying to create a new object involves creating another copy of the same object then you will end up with infinite recursion which will then cause the failure.
So you can create a new object anywhere you like - so long as it is not inside the creation of itself.
class A {
A a = new A(); // Recursion
}
class A {
A() {
A a = new A(); // Recursion
}
}
class A {
A getNewA() {
return new A();
// This is fine as it doesn't happen during creation of an A
}
}
class A {
A() {
getNewA();
// Recursion as calling getNewA creates a new A, which calls getNewA, which....
}
A getNewA() {
return new A();
// This is fine on its own but is broken if called from the constructor
}
}
class B {
A a = new A();
// This is fine as B is not A, so you can create a new A within B.
}
Let's step through this visually.
Arrayprg = new Arrayprg();
So what do you need to create an object of type Arrayprg? Well you need to create it's fields.
Arrayprg = new Arrayprg();
And once again, you're telling the JVM to give you another Arrayprg object. By definition, this means making another Arrayprg object.
This is giving you a StackOverflowException.
Solution?
You shouldn't really be nesting types like this. It's pointless. You're inside the class already, so use it's methods.
public void declarearray()
{
int[] arr;
arr = new int[11];
assignarr(arr);
}
Follow this pattern, and you'll eliminate the need for the Arrayprg field.
Every time you create an instance of Arrayprg, you call this line: Arrayprg = new Arrayprg();, this means every time you create one, it creates another and another and another etc. You can instantiate objects there, but instantiating another object of the same type causes your infinite loop.
Also, in your methods (declareArr, assignArr etc) you can remove the 'new Arrayprg().' and just call the functions on the existing object.
In a class you can create objects outside any method, object cannot be of the same class.
It is meaningless. Take it as a rule.

What's the difference between calling through and object vs class

What's the difference between calling a method through an object vs a class.
for example the Class Bob
public class SecretNumber() {
public static int secretNumber = 2;
public static void changeSecretNumber(){
secretNumber++;
}
}
What would be the difference if i called it like an object
SecretNumber secretNumber = new SecretNumber();
secretNumber.changeSecretNumber();
vs calling it like this
SecretNumber.changeSecretNumber();
How would one method effect the other?
The result is the same.
You should call it by class name, not through the instance, because no dynamic dispatch happens.
Most compilers will give you a warning, if you do that, too. Some people argue that it should have been made a compile error.
In Java, unless a class method is "static", you can't call it except through an object instance.
Here's an example of a method where it would make sense to declare it "static":
http://www.leepoint.net/notes-java/flow/methods/50static-methods.html
public static double mean(int[] p) {
int sum = 0; // sum of all the elements
for (int i=0; i
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
The second form isn't valid Java. You can only call methods on a class if they are declared static.
Calling a method through a class is a static method. Unless you declare the method a static method, the compiler will give you a compile error .

Why am I having problems calling this method from a different class?

I am an eighth grader with a tight deadline on a java project. I have my GUI all ready to go, except I need to take the two values from the two text fields, and send them to a method in a different class when I press a button. I am having trouble calling the method I need. All important code is below.
Code that is attempting to call the method:
private void GoButtonActionPerformed(java.awt.event.ActionEvent evt) {
String Ntextfield = NumberTextField.getText();
n = Integer.parseInt(Ntextfield);
String Rtextfield = RateTextField.getText();
r = Integer.parseInt(Rtextfield);
//call PermMath class
PermMath doTheMath = new PermMath();
doTheMath.permutations(int n, int r);
}
Method I am trying to call:
class PermMath {
static long factorial(int num){
//other code is here
}
static long permutations(int n, int r){
//code I want to call is here
}
}
The hint for you is the static keyword. Learn what it means and how it works.
Also, you're using the variables n and r even before declaring them.
n = Integer.parseInt(Ntextfield);
should come after you've done something like int n = 0;.
And while invoking a method, you don't declare the parameters. The below is wrong.
doTheMath.permutations(int n, int r);
Instead you do something like
doTheMath.permutations(n, r);
It seems to me you have two mistakes:
You are passing two temporary integers called n and r instead of passing the two integers you modified earlier in your GoButtonActionPerformed function.
The permutations function is static, so there is no need to actually create an instance of the PermMath class.
Changing the function call to this should do it:
PermMath.permutations(n, r);
Note that if PermMath is in another package than the class which defines GoButtonActionPerformed(...) it won't be visible due to the lack of a public access modifier on the methods and even the class.
Btw, in Java method names should start with a lower case latter. While your style is valid code adhering to the convention makes it easier for other Java developers to read your code.
Another thing: you don't use the return value of permutations(...). That might not be intented.
You've declared static methods in your PermMath class - these do not require an instantiation of the class to be called. You simply call them with:
PermMath.permutations(n,r);
Check out the track for this at: http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

Categories