static keyword by itself in Java - java

I know what static is.. Globally.
So I was looking through a code, to get better in coding myself. I'm looking through the Minecraft source code, and for those who are interested to look there its in the files "TileEntity.java" and "EntityList.java". It is definitely not necessary to look over there, because its just a manner of programming.
So, we have just your regular class with a method:
public class EntityList{
public static void addMapping( /* variables that dont matter */ ){
//Call other methods, also unimportant
}
}
After that there is a class that imported EntityList and does this:
import the.path.to.EntityList;
public class TileEntity{
static{
addMapping( /* vars */ );
addMapping( /* vars */ );
}
}
Now I'm wondering: How does this work? Please let me know if you need to know more background of the code, but I cannot redistribute the file due to copyright and stuff. Then you have to decompile Minecraft if you have it yourself.

We can't see the real code, but my guess is that it contains a static import:
import static the.path.to.EntityList.addMapping;
or
import static the.path.to.EntityList.*;
A static import allows referring to a static field or method of a class without having to type the name of the class.
See http://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html for more details.

Related

Why do I get different compilation result depending on java imports and static imports sequence order?

I've faced an issue with compilation, but cannot understand why it occurs.
Actually much time was spent to understand where the reason is (it was far from obvious in a "crap" project), but after reproducing that error I greatly simplifies all the code to show a little example especially for you:
Package structure:
com.company
|
----Main.class
|
----maker
|
----Maker.class
Maker.class
package com.company.maker;
public interface Maker {
}
Main.class
package com.company;
import static com.company.Main.MakerImpl.Strategy.STRATEGY1;
import static com.company.Main.MakerImpl.Strategy.STRATEGY2;
import com.company.maker.Maker;
public class Main {
public static void main(String[] args) {
System.out.println(STRATEGY1.name() + STRATEGY2.name());
}
static class MakerImpl implements Maker {
enum Strategy {
STRATEGY1, STRATEGY2
}
}
}
And I got compilation error in Main class:
Error:(15, 39) java: cannot find symbol
symbol: class Maker
location: class com.company.Main
And if I change the import sequence from
import static com.company.Main.MakerImpl.Strategy.STRATEGY1;
import static com.company.Main.MakerImpl.Strategy.STRATEGY2;
->import com.company.maker.Maker;
to
->import com.company.maker.Maker;
import static com.company.Main.MakerImpl.Strategy.STRATEGY1;
import static com.company.Main.MakerImpl.Strategy.STRATEGY2;
then it is compiled successfully.
Is it normal behaviour of Java Compiler? If so I want to clearly understand why it happens.
P.S. tested using java version 1.8.0_112 and 1.7.0_80 (MacOS)
check this :
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6391197
It seems that the compiler sees the first static import and then jumps to take care of your inner class, but fails because it did not read the last non static import.
So when you change the import order, this problem does not occur, since when the compiler reads the static import and jumps to take care of the inner class because those imports are used in the inner class, the compiler is happy since it already imported the non static Maker Interface.
Wich means that the imports are evaluated eagerly.
I hope this helps.
See also Java how import order matters when import class/enum inner an inner class to see that this problem also exists with non static imports.

Dynamic class load in Java - refer classes

I am just testing dynamic class load and am doing this:
package P1;
public class Class1
{
public static void main(String[] args)
{
Bird myBird = null;
String myClassName = "P2.Bird";
Class x = Class.forName(myClassName);
myBird = (Bird)x.newInstance();
}
}
Bird is a class from package P2, and Class1 is from P1. What should I add in the code to make this work, as the String myClassName... line shows an error (class not found). I tried the same code after moving Bird in package P1, even then it doesn't work.
Related question: Why would someone use dynamic class load, does it have any advantages? It's much simpler(at least for me at first glance) to just use the "new" operator for static class loading, and in that case I know how to refer the class from a different package. Many thanks!
For the answer to your first question try mentioning full Package name. I have tried it and it works
Your Bird class provides a default public constructor with no arguments?
Dynamic class loading can be useful for example to specify the class you want to use in a configuration file (you will come across that if you ever use log4j, or other libraries that allow the use of your own implementation to one of their interfaces). In that case, the library does not know about which class you will use, and you don't have to write code to initialise the library (which would be the alternative to dynamic class loading, but which is less convenient)

How to use if(DEBUG) in java in eclipse?

I know I'm throwing a pretty stupid question, but I promise I did try to search around the settings and around google and the webs and no luck, so I guess I should just ask.
I saw in quite a few open-source projects the following line:
if(DEBUG){
// do some logging
}
I perfectly understand what the line is doing, I just can't seem to repeat it.
There's no declaration of boolean DEBUG; anywhere in the code, and I couldn't figure out a place on the project properties to define a system wide variable to be replaced on the compiling (into byte code). And as far as I know, if it's a reference to a class constant it was supposed to be Log.DEBUG or something similar.
Can anyone solve this mystery for me?
thanks.
You really should look at the import section of the class.
It is probably a static import, like this :
A.java
public class A {
public static boolean DEBUG = false;
}
B.java
import static A.DEBUG;
public class B {
public void myMethod() {
if (DEBUG) {
// do something
}
}
}
You are in front of a public static field, look in import list and pick the original class or, use the inline help from Eclipse as said in comments

Classes in same package

I love the Intellij IDEA but i have been stacked on one little problem with Java imports.
So for example there is a package with name "example" and two different classes in it: A.java and B.java.
And i wanna get access to class "A" from class "B" without imports. Like this:
class A:
package example;
public class A{ ... some stuff here ...}
class B:
package example;
public class B{
public static void main(String[] args){
A myVar = new A();
}
}
This code may not work, but it's doesn't matter. Trouble just with IDE and with its mechanism of importing classes.
So, problem is that i can't see A class from B. Idea says 'Cant resolve symbol' but i actually know that class A exists in package. Next strange is that complier works fine and there are no exceptions. Just IDEA can't see the class in the same package.
Does anybody has any ideas?
If they are in the same package, you can access A in class B without import:
package example;
public class B{
public static void main(String[] args){
A myA = new A();
}
}
Maybe this will help you, or somebody else using IntelliJ that is getting a "Cannot resolve symbol" error but can still compile their code.
Lets say you have the two files that buymypies wrote up, the standard Java convention is that the two files would exist in an Example directory in your source code area, like /myprojectpath/src/Example. But it is technically not a requirement to reflect the package structure in the source directory structure, just a best practice sort of thing.
So, if you don't mimic the package structure, and the two files are just in /myprojectpath/src, IntelliJ will give you the "Cannot resolve symbol" error because it expects the source code structure to reflect the package structure, but it will compile okay.
I'm not sure if this is your problem, but I do use IntelliJ and have seen this, so it's something to look at.
I have the same problem as this: 2 classes in the same package, yet when one tries to call the other, Intellij underlines it in red and says Cannot resolve symbol 'Classname', e.g. Cannot resolve symbol 'LocalPreferencesStore'.
It then wants to add the fully qualified name in situ - so it clearly knows the path - so why can't it just access the class?
The module still compiles and runs, so it's just the IDE behaving oddly - and all that red is very distracting, since it isn't actually an error, it's just IDEA throwing a weird wobbly.
This is also recent. Two weeks ago I wasn't having this problem at all, and now suddenly it's started up. Of course, it could go away again on its own soon, but it's really annoying.
Same issue and I just fixed it.
I don't know your folder structure.
However, if your package example was added manually.That's the problem.
The package should be the same as your folder structure,which means if you want your class file to be stored in package example,you must store you java file in the src's subfolder named example.
You need to learn the basics about Java i think.
Here is a basic example of what i think you are trying:
package Example;
public class A
{
String myVar;
public String getMyVar()
{
return myVar;
}
public void setMyVar(String myVar)
{
this.myVar = myVar;
}
}
You need to create an instance of A.
package Example;
public class B
{
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
A myA = new A();
myA.setMyVar("Hello World!");
System.out.println(myA.getMyVar);
}
}
Look up java 'getters' and 'setters'.

how to implement a java class so that it holds constants for other classes in other files

What is the best way to implement a system to establish program-wide constants? I have a program that spans several files and I want to have a class that stores constants so that they are available for all the other files.
I tried something like this:
in Constants.java
public final class Constants{
private Constants(){}
public static final String EX = "mas";
}
and in test.java
import Constants.*;
public class test{
public static void main( String[]args){
System.out.println( EX );
}
}
but I get the following error
test.java:1: error: cannot find symbol
import static Constants.*;
^
symbol: class Constants
Constants.java and test.java are in the same dir.
You can not import from the default package. See Java Language Specification
Put the class in a package.
You can't import classes without a package (also called the default package)
If these two classes are in the same package, you do not need to import.
Remove the import statement for Constants class
In your test class, use the following line: Constants.EX to get the value of EX.
You'll need to preface your reference to Constants in the import with the full package name.
For example, if Constants and test are in the package "com.mystuff", you'll need to import as follows:
import static com.mystuff.Constants.*;
Alternatively, since your classes are in the same package you don't really need the import at all - just qualify EX with the Constants class, e.g. Constants.EX instead of just EX.
Any public static final variable will be accessible anywhere without creating an instance of an object. In your case you can access the EX variable with:
Constants.EX;
In general with good object-oriented design the constants which you include in a class should be specific to that object type. For example if you have a Window object its constant might be "aspectRatio" or "height" but it would be inappropriate to have "nameOfUser" in a Window class as a constant. So sometimes making a "universal" Constants class will inherently make you lose sight of which variables truly belong in different classes when following object-oriented ideals.

Categories

Resources