I have a class as follows:
package org.requiredinput.rpg1.desktop;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import org.requiredinput.rpg1.Rpg1;
public class DesktopLauncher {
public static void main (String[] arg) {
LwjglApplicationConfiguration config =
new LwjglApplicationConfiguration();
config.title = "Awesome rpg";
config.width = 800;
config.height = 480;
new LwjglApplication(new Rpg1(), config);
}
}
My question is - on the last line, the new statement is used without being preceded by an =.
What is being created? A new LwjglApplication object? Class?
And why doesn't it need to be instantiated like app = new LwjglApplication() for example?
Your code creates a new object and doesn't give it a name, which means that it can't be used by main() afterwards. The code in the constructor will still run, and an object of type LwjglApplication will still be created. main() won't hold a reference to it, though.
This is just like when you call a function that returns a value without assigning it to a variable:
int foo() {
System.out.println("Ron Paul 2016!");
return 42;
}
public static void main(String... args) {
foo(); // will print out "Ron Paul 2016!" (w/o quotes)
}
Here, nothing is being done with the return value from foo() but the println() call will still run.
This is commonly used when the constructor (in this case, that of LwjglApplication) has a beneficial side-effect. In your specific case, a window is being popped up as a result of the constructor. (As RafazZ said, you don't need to access the object that's being constructed because there are other ways to access it, provided through the third-party vendor's API.)
As Drew Kennedy mentioned in a comment, this pattern is also used for single-use objects.
Let's say you have a class that looks like this:
class Foo {
void bar() {
// stuff that requires being in an instance, such as...
System.out.println(this.getClass());
}
public static void main(String... args) {
(new Foo()).bar();
}
}
Note that the program doesn't bother assigning a name to the newly created Foo object, since it's only being used for the benefit of calling its bar() method.
According to the BadLogic documentation, LwjglApplication creates a lightweight fullscreen window. This is sometimes done when designing stuff like games - you create a window, and then forget about it, because you don't need to modify it explicitly. You can still modify it using other methods - for that you need to get more familiar with the API provided by the vendor (BadLogic in your case).
Here is a top level description for LwjglApplication.
TL;DR UPDATE: Once DesktopLauncher is called it will create an OpenGL fullscreen window object by calling new LwjglApplication. Every time you call an OpenGL method, it will assume that you are implying the object that was created in the DesktopLauncher.
An LwjglApplication object is being created, but not ASSIGNED to a variable.
So essentially you can't access it later. But it exists.
An object is being created but you are not assigning it a label. It is very likely the author is just interested in calling LwjglApplication constructor.
Contrary with what others have stated, the object created is not necessarily up for garbage collection. There are a few ways the object can actually stay alive depending on the particular object, e.g., Singleton.
new MyClass() is a constructor call syntax in Java. Constructor is a special method, which returns a constructed object. It has some nuanses, but generally can be regarded as just method call.
So new without assignments is just calling a function and not using it's return value.
It is possible for all functions in Java (not to use return value).
The reason can be side effects, for example. Thus constructor may register it's result in some global static list.
If return value is an object and it is really not used, then it will be garbage collected later, as with every unused object.
Example:
package tests;
public class Runner {
public static class Line {
public Line(String line) {
System.out.println(line);
}
}
public static void main(String[] args) {
new Line("Hello world");
}
}
Related
I think I am missing something. I want to call a method in an object from a statement in an object of a different class but if I do that the compiler tells me that it cannot find symbol.
public class Test1
{
public static void main (String[] args)
{
Second secondObj1 = new Second();
Third thirdObj1= new Third();
thirdObj1.accessMethodinSecondObj1();
}
}
class Second
{
int m1;
Second()
{
m1 = 0;
}
public void methodinSecond()
{
System.out.println(m1);
}
}
class Third
{
void accessMethodinSecondObj1()
{
secondObj1.methodinSecond();
}
}
So what I am trying to do is run method secondObj1.methodinSecond() from thirdObj1.accessMethodinSecondObj1(). Obviously, this example is a bit silly but it is related to a real problem - but I feel the full code would be too confusing.
I can solve the problem by passing the object reference for secondObj1 to thirdObj1 by changing the signature etc., but it seems very convoluted. Maybe there is a better way?
It seems to me that because I declared secondObj1 in the main method then the object itself is only visible within the main scope? Is there no way to allow objects of Second and Third to "talk" to each other directly, meaning call each other's methods?
secondObj1 is a local variable of the main method. A local variable is visible only in the block where it's declared. So it's visible only inside the main method. Not inside the method accessMethodinSecondObj1 of Third.
If you want this method to access the object referenced by `secondObj1, you need to pass that object as argument to the method:
In main:
thirdObj1.accessMethodinSecondObj1(secondObj1);
In Third:
void accessMethodinSecondObj1(Second s) {
s.methodinSecond();
}
Just like, to print the value of m1, you pass m1 as argument to the method println() of System.out.
The compiler message is about scope, yes.
But there is a more fundmental flaw in your code. What is you have another Second object and you want to call a method in that one? Your Third class objects expect any Second class object to be named 'secondObj1'.
You already indicated an solution, change te signature so that the object of class Second you want to access can be passed:
void accessMethodinSecondObj(Second secondObj)
{
secondObj.methodinSecond();
}
And then:
thirdObj1.accessMethodinSecondObj(secondObj1);
You're along the right lines. You are correct that the scope of secondObj1 is limited to the main method where it is created. So how do we pass secondObj1 to thirdObj1, as they're not globally available?
This first thing to note is that these objects have a relationship. Our class Third has a dependency upon Second. Third can't perform its responsibility in accessMethodinSecondObj1() without an instance of Second. In which case, we have a few options.
Thie simplest of which is to inject the dependency where it is needed. In this case, into the accessMethodinSecondObj1() method as such:
public class Third
{
public void accessMethodinSecondObj1(Second secondObj1)
{
secondObj1.methodinSecond();
}
}
To call this from main, simply:
public class Test1
{
public static void main (String[] args)
{
Second secondObj1 = new Second();
Third thirdObj1 = new Third();
thirdObj1.accessMethodinSecondObj1(secondObj1);
}
}
You could inherit from Second as to access its members and methods and call from within thirdObject1.accessMethodinSecondObj1() using super.methodinSecond(). But as we're dealing in abstractions here, it's a difficult solution to suggest as it may not make semantic sense in your domain.
In which case, another option is composition. We inject an instance of Second into Third via the constructor and that instance of Third then owns that instance of Second. By doing so, we ensure Third has an instance of Second (upon which it depends) when this method is called. This also enables the performing of validation operations on the passed instance of Second before we use it in accessMethodinSecondObj1().
public class Third
{
private Second secondObj1;
public Third(Second secondObj1)
{
this.secondObj1 = secondObj1;
}
public void accessMethodinSecondObj1()
{
this.secondObj1.methodinSecond();
}
}
In which case, within main we would do the following:
public class Test1
{
public static void main (String[] args)
{
Second secondObj1 = new Second();
Third thirdObj1 = new Third(secondObj1);
thirdObj1.accessMethodinSecondObj1();
}
}
As we can see
public void methodinSecond()
{
System.out.println(m1);
}
is not static and therefore in
secondObj1.methodinSecond();
you cannot call a method without creating an object if it is non-static
In your main method
Second secondObj = new Second();
the scope of the variable would be only inside the block so if you want to use it in the method of class Third pass it as a parameter to the method
thirdObj1.accessMethodinSecondObj1(secondObj);
and also change the method to
void accessMethodinSecondObj1(Second secondObj)
{
secondObj.methodinSecond();
}
If I understand the meaning of each keyword correctly, public means the method is accessible by anybody(instances of the class, direct call of the method, etc), while static means that the method can only be accessed inside the class(not even the instances of the class). That said, the public keyword is no use in this situation as the method can only be used inside the class. I wrote a little program to test it out and I got no errors or warnings without putting the public key word in front of the method. Can anyone please explain why public static methods are sometimes use? (e.g. public static void main(String[] args))
Thank you in advance!
Static methods mean you do not need to instantiate the class to call the method, it does't mean you cannot call it from anywhere you want in the application.
Others have already explained the right meaning of static.
Can anyone please explain why public static methods are sometimes use?
Maybe the most famous example is the public static void main method - the standard entry point for java programs.
It is public because it needs to be called from the outside world.
It is static because it won't make sanse to start a program from an object instance.
Another good examle is a utility class, one that only holds static methods for use of other classes. It dosen't need to be instantiated (sometimes it even can't), but rather supply a bounch of "static" routines to perform, routines that does not depend on a state of an object. The output is a direct function of the input (ofcourse, it might also be subject to other global state from outside). this is actually why it is called static.
That said, the static keyword is not always used because you want to have access to some members in a class without instantiating it, but rather because it makes sense. You keep a property that is shared among all instances in one place, instead of holding copies of it in each instance.
That leads to a third common use of public static (or even public static final) - the definition of constants.
A public static method is a method that does not need an instance of the class to run and can be run from anywhere. Typically it is used for some utility function that does not use the member variables of a class and is self contained in its logic.
The code below chooses a path to store an image based on the image file name so that the many images are stored in a tree of small folders.
public static String getImagePathString(String key){
String res = key.substring(3, 4)+File.separator+
key.substring(2, 3)+File.separator+
key.substring(1, 2)+File.separator+
key.substring(0, 1);
return res;
}
It needs no other information (it could do with a safety check on the size of key)
A quick guide to some of the options...
public class Foo {
public static void doo() {
}
private static void dont() {
}
public Foo() {
doo(); // this works
dont(); // this works
Foo.doo(); // this works
Foo.dont(); // this works
this.doo(); // this works but is silly - its just Foo.doo();
this.dont(); // this works but is silly - its just Foo.dont();
}
public static void main(String[] args) {
doo(); // this works
dont(); // this works
Foo.doo(); // this works
Foo.dont(); // this works
Foo foo = new Foo();
foo.doo(); // this works but is silly - its just Foo.doo();
}
}
public class Another {
public static void main(String[] args) {
Foo.doo(); // this works
Foo.dont(); // this DOESN'T work. dont is private
doo(); // this DOESN'T work. where is doo()? I cant find it?
}
}
Whenever we use static, we need not create a reference variable of a class. We can directly access class with the help of <class_name>
But when we write the following code:
class Abc
{
static void show()
{
System.out.println("Hey I am static");
}
}
class Test
{
public static void main(String args[])
{
Abc.show(); //1
new Abc().show(); //2
}
}
How does both the lines 1 & 2 work. what is the significance of
new Abc().show();
Using an instance (although it works) is the wrong way of invoking a static method (or access static fields) because static denotes its a member of the class/type and not the instance.
The compiler would therefore replace the instance with the Class type (due to static binding). In other words, at runtime, ABC.show() gets executed instead of new ABC().show().
However, your source code would still look confusing. Hence, it's considered a bad practice and would even result in warnings from IDEs like Eclipse.
Since your ABC class did'nt override the default constructor.
It's equivalent to :
class Abc{
public Abc(){super();}
static void show(){
System.out.println("Hey I am static");
}
}
Hence by doing new Abc().show(); you're just creating a new Abc object of your class and call the static method of the ABC class throught this object (it will show a warning because this is not the proper way to call static method).`
You CAN use static methods from an instance, as in new Abc().show(), but it's potentially confusing and not recommended.
Stick to className.staticMethod() for static methods and classInstance.instanceMethod() otherwise.
It simple means that you are creating object to ABC and than trying to accessing this variable through object.
However, at the time of compilation,
new Abc().show();
is converted to Abc.show().
Static keyword suggests only one copy per class now you have created method static and you are accessing using Classname.methodname() that is appropriate way because when class is loaded into JVM its instance will be created so no need to exlicitly create new Object of the class. hope it make sense.
I have a simple Java theory question. If I write a class that contains a main() method along with some other methods, and within that main method invoke an instance of the class (say new Class()), I'm a bit confused why a recursion doesn't occur. Let's say I'm writing a graphing program, where the other methods in the class create a window and plot data; in the main method I call an instance of the class itself, and yet only one window appears. That's great, and it's what I wanted, but intuition suggests that if I create an instance of a class from within itself, some sort of recursion should occur. What prevents this? Here is an example (in my mind, I'm wondering what prevents unwanted recursion):
public class example{
method1(){create Jpane}
method2(){paint Jpane}
method 3(){do some computations}
public static void main(String[] args){
new example(); // or create Jblah(new example());
}
}
I think you're confusing the main method - which is just the entry point of the program - with a constructor.
For example, if you wrote:
public class Example {
public Example() {
new Example(); // Recursive call
}
public static void main(String[] args) {
// Will call the constructor, which will call itself... but main
// won't get called again.
new Example();
}
}
Then that would go bang.
The main method does not get executed automatically when you instance a class. It simply can be used as an entry point to an application - and then will be executed once.
Recursion isn't a bad thing. I suspect you are asking why there isn't an infinite recursion.
The big concept you are missing is that when you call new Example() you are allocating memory and then invoking just one method (the constructor). The main() is only invoked at the start of the whole program unless you explicitly call it.
--- edited to add
public class MyMainClass {
public static void main(String arg[]) {
Calculator c = new Calculator();
int x = c.factorial(5);
}
}
class Calculator {
Calculator() { }
public int factorial(int x) {
if (x > 1) return x * factorial(x - 1);
else return 1; // WARNING: wrong answer for negative input
}
}
Since factorial doesn't use any instance variable, it could have been declared static and called as Calculator.factoral(5); without even using new, but I din't do that since showing off new was the whole point of the example.
just because you have a main method in the class doesn' mean that it will be called every time you create the class.
Java looks for main as an entry point for the program, and calls it upon startup. Any objects you instantiate from their do not call main, since as far as java is concerned, it has done its job of making the entry point to the program.
Suppose the classes has code like this:
class C {
public static void show() {
}
}
class CTest {
public static void main (String[] args) {
C.show();
}
}
Then will it be perfectly legal to conclude that while referring to class C to access the static method show() here, behind the scene Java is actually calling the show() method through Java reflection ?
I.e. is it actually doing something like this
Class test = Class.forName(C);
test.show();
to call static methods?
If not, then how is it actually calling the static methods without creating objects?
If the above explanation is true, then how we'll justify the statement that "static members are only associated with classes, not objects" when we're actually invoking the method through a java.lang.Class object?
The JVM doesn't need to do anything like Class.forName() when calling a static method, because when the class that is calling the method is initialized (or when the method runs the first time, depending on where the static method call is), those other classes are looked up and a reference to the static method code is installed into the pool of data associated with that calling class. But at some point during that initialization, yes, the equivalent of Class.forName() is performed to find the other class.
This is a specious semantic argument. You could just as easily say that this reinforces the standard line that a static method is associated with the class rather than any instance of the class.
The JVM divides the memory it can use into different parts: one part where classes are stored, and one for the objects. (I think there might have been third part, but I am not quite sure about that right now).
Anyways, when an object is created, java looks up the corresponding class (like a blueprint) and creates a copy of it -> voila, we have an object. When a static method is called, the method of the class in the first part of the memory is executed, and not that of an object in the second part. (so there is no need to instantiate an object).
Besides, reflection needs a lot of resources, so using it to call static methods would considerably impact performance.
For extra info:
The called class will get loaded when it's first referenced by calling code.
i.e. The JVM only resolves and loads the class at the specific line of code that it first needs it.
You can verify this by using the JVM arg "-verbose:class" and stepping through with a debugger.
It will call ClassLoader.loadClass(String name) to load the class.
You can put a println statement into the ctor, to verify, whether it is called or not:
class C {
public static void show () {
System.out.println ("static: C.show ();");
}
public C () {
System.out.println ("C.ctor ();");
}
public void view () {
System.out.println ("c.view ();");
}
}
public class CTest
{
public static void main (String args[])
{
System.out.println ("static: ");
C.show ();
System.out.println ("object: ");
C c = new C ();
c.view ();
c.show (); // bad style, should be avoided
}
}