Related
I seen this bit of code, Even though I think I got the concept of static in Java I am bit confused. Can any one explain it to me, how an object being static works?
My code:
package com.oracle.certification.sampleTest;
public class Person {
static class Mail {
static String desc="Male";
}
static Gender Mail=new Gender();
}
package com.oracle.certification.sampleTest;
public class Gender {
String desc="Gender";
}
package com.oracle.certification.sampleTest;
public class Human {
public static void main(String str[]) {
System.out.println(Person.Mail.desc);
}
}
When the class Human is run, the O/P is 'gender' not 'male', even though des= gender is nonstatic and des=male is static with static inner class. Also I don't need to import the classes in Hman? I am sorry that I have very little knowledge about inner classes, first of all.
Can any one explain it to me, How an object being static works?
Essentially, static in that context means that the entity in question is attached to the class itself, not to an object of the class. Hence, with static there is exactly one instance of what you declare:
class T {
public static int staticMember = 0; // one variable stored in memory
public int nonStaticMember = 0; // as many variables stored in memory as objects are created from the class
}
See also What does the 'static' keyword do in a class?
However, your question is not necessarily a misunderstanding of static classes, but a corner case of name resolution: You are declaring both a type and a member variable with the same name (Mail) in one scope (within the Person class) - while one might think that this should not even be possible, the Java language does allow this and defines a couple of rules to determine which one to use.
From the JLS:
A simple name may occur in contexts where it may potentially be interpreted as the name of a variable, a type, or a package. In these situations, the rules of §6.5 specify that a variable will be chosen in preference to a type.
...
static class Mail { // a Type
}
static Gender Mail ... // a Variable with the same name
// - the compiler chooses to use this one
...
Hence, when referencing Person.Mail, the compiler chooses the variable, not the type (the inner class).
I am using a class to store some strings which I can access across the application. It looks like:
public final class Settings {
public final static class Setting1 {
public final static String CONFIG = "A config string";
private Setting1 (){};
}
public final class Setting2 {
public final static String CONFIG = "A config string";
private Setting2 (){};
}
}
I have found I can use either static nested class (e.g. Setting1) or inner class (e.g. Setting2). They both can be used in the same way:
System.out.println(Settings.Setting1.CONFIG); // Print: A config string
System.out.println(Settings.Setting2.CONFIG); // Print: A config string
So if the nested class will only contain final static fields, are there any different in using these two? Because of the private constructor, no instantiation is allowed. Does that mean these two classes are the same now?
A nested/inner class should be marked static if it does not access the this of the outer class, no non-static fields or methods of the outer class.
In fact it is the other way around: a non-static inner class has an overhead of an outer this: a Settings.this besides the normal this.
So yes, in your case certainly. The reason / role of that inner class is of course style / namespace.
If you wish to store only static final fields, then enum will be better choice than inner class. In fact, you are storing constants using static final fields and enum are provided for this purpose only.
There's no difference in storing such constants. But it's usually not a good code-style.
Yes.
Ordinary constants should always be static and final (and immutable, which is not the same thing as final). If you are going to do it the way you have the inner classes should be static too. You should probably include a private constructor too - to prevent instances of these classes (the inner or the outer) being created.
That said, what would be wrong with?
public final class Settings {
private Settings() { ; }
public static final String SETTING_1 = "A config string";
public static final String SETTING_2 = "Another config string";
}
Re the answer from Florescent Ticket:
Enums are not for storing static final fields (though their members are static final fields). They are for defining a typed, bounded set (with or without further attributes on the members of the set). A typical example is public enum Suit { HEART, CLUB, SPADE, DIAMOND };.
You could represent your Settings this way (with a single String attribute on each member of the enum) but there is no real reason why you should. It might be helpful if you routinely need to deal with sets of settings (and I mean sets of settings - not sets of the values of those settings). On the other hand, it might be less than helpful if you want settings that are not just strings.
The simplest starting point is probably too just define a class with public static final constants (they should be immutable too, of course) of the appropriate values - whether strings or whatever. But if you want inner classes (perhaps to group the settings) then the inner classes should be static and final (and ideally, also have a private constructor, to prevent instances).
I'd like to have Java constant strings at one place and use them across whole project (many classes).
What is the recommended way of achieveing this?
public static final String CONSTANT_STRING="CONSTANT_STRING";
constants should be:
public - so that it can be accessed from anywhere
static - no need to create an instance
final - since its constants shouldnt be allowed to change
As per Java naming convention should be capitalized so that easy to read and stands out in Java documentation.
There are instances where interfaces are used just to keep constants, but this is considered a bad practice because interfaces are supposed to define the behavior of a type.
A better approach is to keep it in the class where it makes more sense.
for e.g.
JFrame has EXIT_ON_CLOSE contant, any class which subclasses JFrame will have access to it and it also makes sense to keep in JFrame and not in JComponent as not all components will have an option to be closed.
As #mprabhat answered before, constants should be public, static, final, and typed in capital letters.
Grouping them in a class helps you:
Don't need to know all the constants you have. Many IDEs (like Eclipse) show you the list of all the fields a class has. So you only press CTRL+SPACE and get a clue of which constants you can use.
Making them typesafe at compile time. If you used Strings, you might misspell "DATABASE_EXCEPTION" with "DATABSE_EXSCEPTION", and only notice during execution (if you are lucky and notice it at all). You can also take profit of autocompletion.
Helping you save memory during execution. You'll only need memory for 1 instance of the constant.
I.E: (a real example) If you have the String "DATABASE_EXCEPTION" 1000 times in different classes in you code, each one of them will be a different instace in memory.
Some other considerations you might have:
Add javadoc comments, so programmers who use the constants can have more semantic information on the constant. It is showed as a tooltip when you press CTRL+SPACE. I.E:
/** Indicates an exception during data retrieving, not during connection. */
public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
/** Indicates an exception during the connection to a database. */
public static final String DATABASE_CONNECTION_EXCEPTION =" DATABASE_CONNECTION_EXCEPTION";
Add semantic to the identifier of the constant. If you have the constant "Y", and sometimes means yes and other times year, consider using 2 different constants.
public static final String Y = "Y"; // Bad
public static final String YEAR = "Y";
public static final String YES = "Y";
It will help you if, in the future, decide to change the values of the constants.
/** Year symbol, used for date formatters. */
public static final String YEAR = "A"; // Year is Año, in Spanish.
public static final String YES = "S"; // Yes is Sí, in Spanish.
You might not know the value of your constants until runtime. IE: You can read them from configuration files.
public class Constants
{
/** Message to be shown to the user if there's any SQL query problem. */
public static final String DATABASE_EXCEPTION_MESSAGE; // Made with the 2 following ones.
public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
public static final String MESSAGE = "MESSAGE";
static {
DATABASE_EXCEPTION_MESSAGE = DATABASE_EXCEPTION + MESSAGE; // It will be executed only once, during the class's [first] instantiation.
}
}
If your constants class is too large, or you presume it'll grow too much in the future, you can divide it in different classes for different meanings (again, semantic): ConstantDB, ConstantNetwork, etc.
Drawbacks:
All the members of your team have to use the same class(es), and the same nomenclature for the constants. In a large project it wouldn't be strange to find 2 definitions:
public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
public static final String EXCEPTION_DATABASE = "DATABASE_EXCEPTION";
separated several hundreds of lines or in different constant classes. Or even worse:
/** Indicates an exception during data retrieving, not during connection. */
public static final String DATABASE_EXCEPTION = "DATABASE_EXCEPTION";
/** Indicates an exception during data retrieving, not during connection. */
public static final String EXCEPTION_DATABASE = "EXCEPTION_DATABASE";
different identifiers, for different values, having the same meaning (and used for the same purposes).
It might make readability worse. Having to write more for doing the same:
if ("Y".equals(getOptionSelected()) {
vs
if (ConstantsWebForm.YES.equals(getOptionSeleted()) {
How should constants be ordered in the class? Alphabetically? All related constants together? In order as they are created/needed? Who sould be responsible of the order being correct? Any (big enough) reordering of constants would be seen as a mess in a versioning system.
Well, it's taken longer than what I expected. Any help/critics is/are welcome.
You should create a class of the constants that stores all the constants.
like ProjectNameConstants.java
which contains all the constant string static as you can access it through the classname.
e.g.
classname : MyAppConstants.java
public static final String MY_CONST="my const string val";
you can access it as
MyAppConstants.MY_CONST
Best practice is to use Java Enum (After Java 5)
Problems with the class approach:
Not typesafe
No namespace
Brittleness
Please check java docs.
public enum Constants {
CONSTANT_STRING1("CONSTANT_VALUE1"),
CONSTANT_STRING2("CONSTANT_VALUE2"),
CONSTANT_STRING3("CONSTANT_VALUE3");
private String constants;
private Constants(String cons) {
this.constants = cons;
}
}
Enums can be used as constants.
Edit: You can call this Constants.CONSTANT_STRING1
Create a class called Constants at the base of your main package (i.e. com.yourcompany) with all your constants there. Also make the the constructor private so no object will be created from this class:
public class Constants {
private Constants() {
// No need to create Constants objects
}
public static final String CONSTANT_ONE = "VALUE_CONSTANT_ONE";
public static final String CONSTANT_TWO = "VALUE_CONSTANT_TWO";
}
public class SomeClass {
public static final String MY_CONST = "Some Value";
}
If it is supposed to be a pure constants class then make the constructor private as well.
public class Constants {
public static final String CONST_1 = "Value 1";
public static final int CONST_2 = 754;
private Constants() {
}
}
Then it won't be possible to instantiate this class.
You should break up your constants into groups they belong, like where they'll be used most, and define them as public static final in those classes. As you go along, it may seem appropriate to have interfaces that define your constants, but resist the urge to create one monolithic interface that holds all constants. It's just not good design.
I guess the correct answer you're looking for is
import static com.package.YourConstantsClass.*;
Create a public class and for each constant string create a field like this
public static final String variableName = "string value";
public enum Constants {
CONSTANT_STRING1("CONSTANT_VALUE1"),
CONSTANT_STRING2("CONSTANT_VALUE2"),
CONSTANT_STRING3("CONSTANT_VALUE3");
private String constants;
private Constants(String cons) {
this.constants = cons;
}
#JsonValue
#Override
public String toString() {
return constants;
}
}
Use it Constants.CONSTANT_STRING1.toString()
How do you define Global variables in Java ?
To define Global Variable you can make use of static Keyword
public class Example {
public static int a;
public static int b;
}
now you can access a and b from anywhere
by calling
Example.a;
Example.b;
You don't. That's by design. You shouldn't do it even if you could.
That being said you could create a set of public static members in a class named Globals.
public class Globals {
public static int globalInt = 0;
///
}
but you really shouldn't :). Seriously .. don't do it.
Another way is to create an interface like this:
public interface GlobalConstants
{
String name = "Chilly Billy";
String address = "10 Chicken head Lane";
}
Any class that needs to use them only has to implement the interface:
public class GlobalImpl implements GlobalConstants
{
public GlobalImpl()
{
System.out.println(name);
}
}
You are better off using dependency injection:
public class Globals {
public int a;
public int b;
}
public class UsesGlobals {
private final Globals globals;
public UsesGlobals(Globals globals) {
this.globals = globals;
}
}
Lots of good answers, but I want to give this example as it's considered the more proper way to access variables of a class by another class: using getters and setters.
The reason why you use getters and setters this way instead of just making the variable public is as follows. Lets say your var is going to be a global parameter that you NEVER want someone to change during the execution of your program (in the case when you are developing code with a team), something like maybe the URL for a website. In theory this could change and may be used many times in your program, so you want to use a global var to be able to update it all at once. But you do not want someone else to go in and change this var (possibly without realizing how important it is). In that case you simply do not include a setter method, and only include the getter method.
public class Global{
private static int var = 5;
public static int getVar(){
return Global.var;
}
//If you do not want to change the var ever then do not include this
public static void setVar(int var){
Global.var = var;
}
}
Truly speaking there is not a concept of "GLOBAL" in a java OO program
Nevertheless there is some truth behind your question because there will be some cases where you want to run a method at any part of the program.
For example---random() method in Phrase-O-Matic app;it is a method should be callable from anywhere of a program.
So in order to satisfy the things like Above "We need to have Global-like variables and methods"
TO DECLARE A VARIABLE AS GLOBAL.
1.Mark the variable as public static final While declaring.
TO DECLARE A METHOD AS GLOBAL.
1. Mark the method as public static While declaring.
Because I declared global variables and method as static you can call them anywhere you wish by simply with the help of following code
ClassName.X
NOTE: X can be either method name or variable name as per the requirement and ClassName is the name of the class in which you declared them.
There is no global variable in Java
Nevertheless, what we do have is a static keyword and that is all we need.
Nothing exists outside of class in Java. The static keyword represents a class variable that, contrary to instance variable, only has one copy and that transcends across all the instances of that class created, which means that its value can be changed and accessed across all instances at any point.
If you need a global variable which can be accessed beyond scopes, then this is the variable that you need, but its scope exists only where the class is, and that will be all.
Nothing should be global, except for constants.
public class MyMainClass {
public final static boolean DEBUGMODE=true;
}
Put this within your main class. In other .java files, use it through:
if(MyMainClass.DEBUGMODE) System.out.println("Some debugging info");
Make sure when you move your code off the cutting room floor and into release you remove or comment out this functionality.
If you have a workhorse method, like a randomizer, I suggest creating a "Toolbox" package! All coders should have one, then whenever you want to use it in a .java, just import it!
There is no such thing as a truly global variable in Java. Every static variable must belong to some class (like System.out), but when you have decided which class it will go in, you can refer to it from everywhere loaded by the same classloader.
Note that static variables should always be protected when updating to avoid race conditions.
Understanding the problem
I consider the qualification of global variable as a variable that could be accessed and changed anywhere in the code without caring about static/instance call or passing any reference from one class to another.
Usually if you have class A
public class A {
private int myVar;
public A(int myVar) {
this.myVar = myVar;
}
public int getMyVar() {
return myVar;
}
public void setMyVar(int mewVar) {
this.myVar = newVar;
}
}
and want to access and update myvar in a class B,
public class B{
private A a;
public void passA(A a){
this.a = a;
}
public void changeMyVar(int newVar){
a.setMyvar(newVar);
}
}
you will need to have a reference of an instance of the class A and update the value in the class B like this:
int initialValue = 2;
int newValue = 3;
A a = new A(initialValue);
B b = new B();
b.passA(a);
b.changeMyVar(newValue);
assertEquals(a.getMyVar(),newValue); // true
Solution
So my solution to this, (even if i'm not sure if it's a good practice), is to use a singleton:
public class Globals {
private static Globals globalsInstance = new Globals();
public static Globals getInstance() {
return globalsInstance;
}
private int myVar = 2;
private Globals() {
}
public int getMyVar() {
return myVar;
}
public void setMyVar(int myVar) {
this.myVar = myVar;
}
}
Now you can get the Global unique instance anywhere with:
Globals globals = Globals.getInstance();
// and read and write to myVar with the getter and setter like
int myVar = globals.getMyVar();
global.setMyVar(3);
public class GlobalClass {
public static int x = 37;
public static String s = "aaa";
}
This way you can access them with GlobalClass.x and GlobalClass.s
If you need to update global property, a simple getter/setter wrapper class can be used as global variable. A typical example is shown below.
public class GlobalHolder {
private static final GlobalHolder INSTANCE = new GlobalHolder();
private volatile int globalProperty;
public static GlobalHolder getInstance() {
return INSTANCE;
}
public int getGlobalProperty() {
return globalProperty;
}
public void setGlobalProperty(int globalProperty) {
this.globalProperty = globalProperty;
}
public static void main(String[] args) {
GlobalHolder.getInstance().setGlobalProperty(10);
System.out.println(GlobalHolder.getInstance().getGlobalProperty());
}
}
public class GlobalImpl {
public static int global = 5;
}
you can call anywhere you want:
GlobalImpl.global // 5
Creating an independent file, eg. Example.java to use the 1st solution, is just fine. You can do that also within the app, if e.g. the global variables are special to your current app, etc.:
Create a class at the beginning and declare your variables in there:
class Globals {
static int month_number;
static String month_name;
}
You can then access these variables -- using them as 'Globals.month_number', etc. -- from averywhere in your app.
very simple:
class UseOfGlobal
{
private static int a;
private static int b;
}
but it is always good to have local variables defined inside method blocks where ever possible.
As you probably guess from the answer there is no global variables in Java and the only thing you can do is to create a class with static members:
public class Global {
public static int a;
}
You can use it with Global.a elsewhere. However if you use Java 1.5 or better you can use the import static magic to make it look even more as a real global variable:
import static test.Global.*;
public class UseGlobal {
public void foo() {
int i = a;
}
}
And voilà!
Now this is far from a best practice so as you can see in the commercials: don't do this at home
There are no global variables in Java, but there are global classes with public fields. You can use static import feature of java 5 to make it look almost like global variables.
Generally Global variable (I assume you are comparing it with C,Cpp) define as public static final
like
class GlobalConstant{
public static final String CODE = "cd";
}
ENUMs are also useful in such scenario :
For Example Calendar.JANUARY)
To allow an unqualified access to static members of another class, you can also do a static import:
import static my.package.GlobalConstants;
Now, instead of print(GlobalConstants.MY_PASSWORD);
you can use the Constant directly: print(MY_PASSWORD);
See What does the "static" modifier after "import" mean? to decide about.
And consider the answer of Evan Lévesque about interfaces to carry the Constants.
// Get the access of global while retaining priveleges.
// You can access variables in one class from another, with provisions.
// The primitive must be protected or no modifier (seen in example).
// the first class
public class farm{
int eggs; // an integer to be set by constructor
fox afox; // declaration of a fox object
// the constructor inits
farm(){
eggs = 4;
afox = new fox(); // an instance of a fox object
// show count of eggs before the fox arrives
System.out.println("Count of eggs before: " + eggs);
// call class fox, afox method, pass myFarm as a reference
afox.stealEgg(this);
// show the farm class, myFarm, primitive value
System.out.println("Count of eggs after : " + eggs);
} // end constructor
public static void main(String[] args){
// instance of a farm class object
farm myFarm = new farm();
}; // end main
} // end class
// the second class
public class fox{
// theFarm is the myFarm object instance
// any public, protected, or "no modifier" variable is accessible
void stealEgg(farm theFarm){ --theFarm.eggs; }
} // end class
Going by the concept, global variables, also known as instance variable are the class level variables,i.e., they are defined inside a class but outside methods. In order to make them available completely and use them directly provide the static keyword.
So if i am writing a program for simple arithmetical operation and it requires a number pair then two instance variables are defined as such:
public class Add {
static int a;
static int b;
static int c;
public static void main(String arg[]) {
c=sum();
System.out.println("Sum is: "+c);
}
static int sum() {
a=20;
b=30;
return a+b;
}
}
Output: Sum is: 50
Moreover using static keyword prior to the instance variables enable us not to specify datatypes for same variables again and again. Just write the variable directly.
In general, Java doesn't have any global variables. Other than local variables, all variables comes under the scope of any class defined in the program.
We can have static variables to have the scope of global variables.
without static this is possible too:
class Main {
String globalVar = "Global Value";
class Class1 {
Class1() {
System.out.println("Class1: "+globalVar);
globalVar += " - changed";
} }
class Class2 {
Class2() {
System.out.println("Class2: "+globalVar);
} }
public static void main(String[] args) {
Main m = new Main();
m.mainCode();
}
void mainCode() {
Class1 o1 = new Class1();
Class2 o2 = new Class2();
}
}
/*
Output:
Class1: Global Value
Class2: Global Value - changed
*/
Object-Oriented Programming is built with the understanding that the scope of variables is closely exclusive to the class object that encapsulates those variables.
The problem with creating "global variables" is that it's not industry standard for Java. It's not industry standard because it allows multiple classes to manipulate data asyncronized, if you're running a multi-threaded application, this gets a little more complicated and dangerous in terms of thread-safety. There are various other reasons why using global variables are ineffective, but if you want to avoid that, I suggest you resort to Aspect-Oriented Programming.
Aspect-Oriented Programming negates this problem by putting the parent class in charge of the scope through something called "advices", which adds additional behavior to the code without actually modifying it. It offers solutions to cross-cutting concerns, or global variable usage.
Spring is a Java framework that utilizes AOP, and while it is traditionally used for web-applications, the core application can be used universally throughout the Java framework (8.0 included). This might be a direction you want to explore more.
To define Global Variable you can make use of static Keyword
public final class Tools {
public static int a;
public static int b;
}
now you can access a and b from anywhere by calling
Tools.a;
Tools.b;
Yoy are right...specially in J2ME...
You can avoid NullPointerException by putting inside your MidLet constructor
(proggy initialization) this line of code:
new Tools();
This ensures that Tools will be allocated before any instruction
that uses it.
That's it!
Right now I'm thinking about adding a private constructor to a class that only holds some String constants.
public class MyStrings {
// I want to add this:
private MyString() {}
public static final String ONE = "something";
public static final String TWO = "another";
...
}
Is there any performance or memory overhead if I add a private constructor to this class to prevent someone to instantiate it?
Do you think it's necessary at all or that private constructors for this purpose are a waste of time and code clutter?
UPDATE
I'm going for a final class with private constructor and a descriptive javadoc for the class. I can't use a ENUM (which I'd prefer) because I'm stuck on Java 1.4 for now. This would be my modification:
/**
* Only for static access, do not instantiate this class.
*/
public final class MyStrings {
private MyString() {}
public static final String ONE = "something";
public static final String TWO = "another";
...
}
Use of private constructor to prevent instantiation of class?
There are several ways you can think of users preventing from the Instantiations for the purpose of creating the Constants
As you have mentioned a class with the private Constructors and has all the string constants, is one way, even there is an overhead, that can be negligible
Else you can create a Class with Final Modifier and Define your string constants
You can use the Abstract Class with the String Constants
You can define the string constants in the properties files and can access from that, this will definitely reduce the memory and increase the flexibility of your code.
For me the best explanation is in Effective Java book: Item 4: Enforce noninstantiability with a private constructor (See more)
In Summary:
Private constructor is due utility classes were not designed to be instantiated, so is a design decision. (NO performance or memory overhead)
Making a class abstract doesn't work because can be subclassed and then instantiated.
With an abstract class the user may think the class is for inheritance.
The only way to ensure no instantiation is to add a private constructor which ensures the default constructor is not generated.
Private constructor prevents inheritance because the super constructor cannot be called (so it is not need the declare the class as final)
Throw an error in the private constructor avoids call it within the class.
Definetively, the best way would be something like next:
public class MyStrings {
private MyStrings () {
throw new AssertionError();
}
...
}
You could add a private constructor, but there are two other options.
In the same situation I would use an enumerator. If it makes sense to your implementation, you could use that instead, if it's public or private depends on where you need to use it:
public enum MyStrings {
ONE ("something"),
TWO ("something else");
private String value;
private MyStrings(String str) {
this.value = str;
}
}
Another option would be to put it in an abstract class, those can not be instantiated:
public abstract MyStrings {
public static final String STUFF = "stuff";
public static final String OTHER = "other stuff";
}
Access for both enumerator and abstract class works just like with the implementation you presented:
MyStrings.STUFF
If you don't won't anyone to make an object of the class you could make it abstract like this
public abstract class MyStrings {
public static final String ONE = "something";
public static final String TWO = "another";
}
and access your static variables like this
String val1 = MyStrings.ONE;
String val2 = MyStrings.TWO;
I think this would be a nicer solution.
I would rather use an enum to hold that Strings. This would ensure that wherever you use that Strings, you only get passed in one of the allowed Strings.
There is no performance or memory overhead if you add a private constructor in this case. As well, it is not needed since your public static variables are shared among all instances of your object.
If your class has only static members, then there is no need to have a private or public constructor. All members are accessible even without an object. In fact I find it confusing to have a constructor in such a case.
A synthetic public constructor would have been generated any way. So no.
Really a few bytes out of hundreds of millions at runtime isn't going to make much difference.
I also suggest making the class final and just for completeness have the constructor throw an exception.
If you want terse source code, you could create an enum with no values. Might cause some confusion with beginner programmers though.
That's the right way to store some constants, as also suggested in Effective Java (2nd Ed.), item 19.