I face a strange error. During the startup of the server, i initialize a set of variables in the init() method of a java class. I could see this value is persisted during the server startup. However, when i try to login through the WebUI, these local variables goes missing.
However, if i assign the variable in a static block, it stays on.
I dont know how this could happen. Any pointers would help.
Java version : JRE1.7.0_40
My piece of code looks like
ClassA.java
public class ClassA { public static String testString; public static
void init() throws Exception {
testString = "testSTring222"; } }
ClassB.java
ClassA.init(); System.out.println(ClassA.testString)
Please help me get out of this.
It certainly depends on what does your server.
Use some static variable.
This could happen due to the usage of multiple class loaders, since static variables are not global across multiple class loaders. i.e. if the same class is loaded in 2 different class loaders, then you will have 2 copies of the static variable.
Class A
public class ClassA
{
public static String testString = "testSTring222";
public static void main(String[] args)
{
}
}
Class B
public class ClassB
{
static ClassA cA = new ClassA();
public static void main(String[] args)
{
System.out.println(cA.testString);
}
}
So you should reference Class A as a static class and make the and set the static string when you first declare it as a variable
Related
I've been thinking about the difference between these code snippets. I understand that you can not set instance field if you are using getInstance (Second option below), but is there other differences?
public class MainClass {
public static MainClass instance;
public static void main(String[] args) {
instance = new MainClass();
}
public void HelloWorld() {
System.out.println("This is a test!");
}
}
VS
public class MainClass {
private static MainClass instance;
public static void main(String[] args) {
instance = new MainClass();
}
public MainClass getInstance() {
return instance;
}
public void HelloWorld() {
System.out.println("This is a test!");
}
}
What is the difference between using "MainClass.instance.HelloWorld();" (First) or "MainClass.getInstance().HelloWorld();" (Second)
TLDR: Which one, and why? What is the difference?
Thanks! :)
In the first example, you have declared instance as public making it vulnerable to accidental changes and therefore it is not recommended.
In the second example, you have declared instance as private making it invisible outside the class and thus ensuring that if required, it can be changed only through a public mutator/setter where you can put the desired logic how you want it to be changed.
Scalability
The difference is somewhere down the line if your program has many calls to the instance, and you want to change where the instance comes from or perform an additional action while retrieving the instance, you can modify the getInstance() method, instead of adding code in every location where you used instance.
Public
Current code is vulnerable by outsider who can change your instance with new one or even their own by subclassing. If you do not have need to change instance after first init then make it final and then public is good.
private
Saves you from above problem. Gives you more control to change instance if needed.
I'm confused about an essential thing in java.
public class InitItself1 {
public InitItself1(){}
private InitItself1 me = new InitItself1();
}
Of course I know that the StackOverFlowError will be occurred when creating an instance of the above class. The above class will be initiated recursively itself because of the initiation of the variable "me".
But,
public class InitItself2 {
public InitItself2(){}
private static InitItself2 me = new InitItself2();
}
Of course the outcome of the above class, "InitItself2" is different to the prior class, "InitItself1". This works just fine, no error occurred. As I know, initiating static variables and executing static blocks are performed when classes in which static variables and blocks are loaded.
What makes me confused is that I think it's the same that the variables, "me" of both classes, "InitItself1" and "InitItself2" are initiated, and also they have references to their classes in which they are, so it looks that "initiating recursively" would happen in initiating both classes.
What is the point that I'm missing?
Good answer please.
Thanks :)
You are not going to get StackOverFlowError in the second case. As you have said yourself, static variables are initiated when the class is loaded, and because a class is only loaded once, the static InitItself2 me will only be instantiated once. Creating a new object with constructor doesn't require the class to be reloaded.
public final class InitItself {
static {
System.out.println("Class is loaded");
}
private static InitItself me = new InitItself();
static {
System.out.println("me is instantiated");
}
public InitItself() {
System.out.println("Constructor called, me=" + me);
}
public static void main(String[] args) {
System.out.println("START");
InitItself i = new InitItself();
System.out.println("FINISH");
}
}
Gives the following output
Class is loaded
Constructor called, me=null
me is instantiated
START
Constructor called, me=oop.InitItself#6ff3c5b5
FINISH
package penny_pinch_v2;
public class Prizes {
public static String[] prizes = { "Puzzle", "Poster", "Ball", "Game", "Doll" };
}
===========Separate Class File============
package penny_pinch_v2;
public class RunPennyPinch {
public static void main(String[] args) {
System.out.print(prizes[1]);
}
}
I'm trying to access the array 'prizes' in a different class, but it keeps saying that 'prizes' cannot be resolved. If you could tell me how to fix this that would be great.
If you are referencing a static field in another class you will need to use the name of that class to reference the field, so basically you need to change your main to this:
public class RunPennyPinch {
public static void main(String[] args) {
System.out.print(Prizes.prizes[1]);
}
}
This is called a namespacing issue. Let's pretend you could do what you're trying to do. What if you make another class called Prizes2 and put another variable in it, also named prizes? How does RunPennyPinch know which prizes variable it should be using?
Perhaps you could solve this problem by saying, "only one prizes variable is allowed to exist in any program at one time". If this were a real limitation, you would quickly run out of meaningful names to give to variables.
The solution that Java came up with is namespacing: To give a variable a context it lives in. Two variables can have the same name, but as long as they have a different context, they won't clash. The price you pay is you have to tell the program which context you want to use when you're referring to a variable.
Here's how to fix the problem:
package penny_pinch_v2;
public class Prizes {
public static String[] prizes = { "Puzzle", "Poster", "Ball", "Game", "Doll" };
}
//===========Separate Class File============
package penny_pinch_v2;
public class RunPennyPinch {
public static void main(String[] args) {
System.out.print(Prizes.prizes[1]);
}
}
There's something else you should know: If you don't explicitly state a context, it defaults to using this as the context. As an unrelated example, these two methods do the same thing and both work:
package foo;
public class Bar {
public String baz = "Puzzle";
public void impliedThis() {
System.out.println(baz);
}
public void explicitThis() {
System.out.println(this.baz);
}
}
You have to prefix the variable with the class name as the variable is not within the RunPennyPinch class.
System.out.print(Prizes.prizes[1]);
You may also have to import the Prizes class, depending on your set-up.
The variable itself doesn't exist in that context. It's a static member of another class. So you need a reference to that class:
System.out.print(Prizes.prizes[1]);
The main advantage of static is that you dont have to create an object to access that variable. You just have to call that variable by Classname.variablename (Classname is the name of class in which that variable was present)
System.out.print(Prizes.prizes[1]);
I understand how to use and import outside packages, but I've never packaged my own classes before. I read the Oracle Tutorial on Creating a Package, and looked at In Java, what's the difference between public, default, protected and private in addition to several sites/SO threads on packages. For the life of me, I can't figure out why this extraordinary simple example doesn't work:
package PTest;
public class A
{
protected final int SIZE = 10;
public void printSize()
{
System.out.println(SIZE);
}
}
package PTest;
public class B
{
public static void main(String[] args)
{
System.out.println(SIZE);
hello();
}
}
I used eclipse's autopackaging feature, so I assume that the actual packing is correct. Here's an image to show that they are indeed packaged correctly:
As you can see, neither the protected SIZE or the public hello() are recognized. I've tried this outside of eclipse, also to no avail. Any help would be greatly appreciated.
SIZE is an instance field of A objects. You need to make it a static field. Even then, it'll be a member of the A class, so you have to specify A.SIZE to use it in B.
Class methods cannot access instance variables or instance methods directly—they must use an object reference.
Errors you getting are fixed here
package PTest;
public class B
{
public static void main(String[] args)
{
A MyClassA = new A();
System.out.println(MyClassA.SIZE);
MyClassA.printSize();
}
}
You can not directly access methods or fields which are not static (instance members) being in a static scope(main) other than using an object and then access or making those instance members as staic.(class members)
A very simple question for the experts, but for a beginner like me, it is just confusing. I thought I understood Static, but apparently I do not. This below is the entire class, and it says I need to make test static. But I don't want to. What can I do to fix this, and why is it happening in the first place? Thanks!
public class SubstringTest
{
private String test;
public static void main(String[] args)
{
test = "Penguin";
System.out.println(test);
System.out.println(test.substring(3));
}
}
main is static. test is not.
If you don't want to make test static, you have to create an instance of SubstringTest first.
SubstringTest st = new SubstringTest(); // create an instance
st.test = "test"; // this works
System.out.println(st.test); // also works
If test is static, you can do
SubstringTest.test = "test";
Or if the code you're writing is in the class SubstringTest and test is static:
test = "test";
A static method cannot access non-static/instance variables, because a static method is never associated with any instance. A static method can’t directly invoke a non-static variable. But static method can access non-static variable by means of declaring instances and using them.
public class SubstringTest
{
private String test; // make it private static String test;
public static void main(String[] args)
{ // SubstringTest t = new SubstringTest(); Or change here.
// t.test ="Penguin";
test = "Penguin";
System.out.println(test);
System.out.println(test.substring(3));
}
}
You CANNOT access instance variables from a Static method.
Because a static method is called on a class instance and not to an object of a class. This means, that a static method is not able to access instance variables, because they are only instantiated in an object