This question already has answers here:
What does .class mean in Java?
(8 answers)
Closed 9 years ago.
For example, in double-checked locking singleton pattern,
public class Singleton {
private volatile static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
synchronized (Singleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
What's the meaning of "Singleton.class"? Is it an object?
Now I know it's class object, then can we use other objects to synchronize here? Such as "this"?
It represents the Class object of that class. Once you get the Class object, you can do a host of things like get the fields of the class, methods of the class, package of the class and so on.
Most commonly, you will use it to get resources as stream. That is, when you want to retrieve an embedded resource from your jar file. For more detailed information, have a look at the documentation
Run the code below directly at: http://ideone.com/h1czR5
SSCCE
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
import java.lang.reflect.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Class string = String.class;
System.out.println("Package: " + string.getPackage());
System.out.println("Fields: " + java.util.Arrays.toString(string.getFields()));
Method[] methods = string.getMethods();
for(int i = 0; i < 10; i++){
System.out.println(methods[i]);
}
}
}
Output:
Package: package java.lang, Java Platform API Specification, version 1.7
Fields: [public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER]
public boolean java.lang.String.equals(java.lang.Object)
public java.lang.String java.lang.String.toString()
public int java.lang.String.hashCode()
public int java.lang.String.compareTo(java.lang.Object)
public int java.lang.String.compareTo(java.lang.String)
public int java.lang.String.indexOf(java.lang.String,int)
public int java.lang.String.indexOf(int)
public int java.lang.String.indexOf(int,int)
public int java.lang.String.indexOf(java.lang.String)
public static java.lang.String java.lang.String.valueOf(float)
For every class in JAVA, there exists an object. That object is a class object.
This object is singleton Object and can be fetched by Class object=ClassName.class or Class object=Class.forName('ClassName');
Read this for more details.
For your code synchronized (Singleton.class) means you are locking on the class, so that the static member access is sychronized.
You are synchronizing on the "class" object. The class object contains some data "about the class".
Related
This question already has answers here:
Calling static method from another java class
(3 answers)
Closed 1 year ago.
In java, I know I can use methods from other class by creating that class in my main myClass newClass = new myClass() and then use methods by doing myClass.myMethod(), where myMethod() is defined in myClass.java, but what if I want a file named utils.java that contains a bunch of useful methods, I just want to use a function that there's in this file, is this possible? How can I import and use the functions from that file?
You do not need to "import" the functions, you would need just to create a class that keeps all your needed functions, and import that class.
I am supposing you use an IDE, you could go to your IDE and create a simple class.
e.g:
public class Utils
{
public static int doSmth(/* Your parameters here */)
{
// Your code here
}
public static void yetAnotherFunction(/* Your parameters here */)
{
// Your code here
}
}
The most important keyword here is static, to understand it I suggest you check my answer here: when to decide use static functions at java
Then you import this class to any of your other classes and call the static functions, without creating an Object.
import package.Utils;
public class MainClass
{
public static void main(String[] args)
{
Utils.doSmth();
}
}
You can add at the beginning:
import
like-
import utils;
Assuming it is in the same package as the current class
Else it should be:
import <package name>.<class name>
Yes, you can import methods but there are caveats. The methods are defined on a class. The methods are defined as static. The import employs the keyword static. Keep in mind that importing methods directly can create confusion and complicate debugging. Consider importing the class and invoke the method from the class. When/whether defining a utility class makes sense and how to implement them are separate discussions.
package some.path;
public class MyUtils {
public static int add(int x, int y) { return x + y; }
}
To import the method
package some.other.path;
import static some.path.MyUtils.add; // note keyword static here
public class MyClass {
private int a, b;
public int sum() { return add(a,b); }
}
Or, import the class and use the method statically
package some.other.path;
import some.path.MyUtils;
public class MyClass {
private int a,b;
public int sum() { return MyUtils.add(a,b); }
}
This question already has answers here:
Non-static variable cannot be referenced from a static context
(15 answers)
Closed 5 years ago.
I get the typical non static variable cannot be referenced from a static context error when I'm attempting to create a new object.
If I make the BookWord class static, everything works. Is that OK in Java?
package javaapplication13;
public class JavaApplication13 {
public class BookWord {
private String wordCharacters;
private int count;
public BookWord(String word){
wordCharacters = word;
}
public String getWord() {
return wordCharacters;
}
public int getCount() {
return count;
}
}
public static void main(String[] args) {
BookWord existing = new BookWord("Hello"); // *** Error here ***
System.out.println("The word is " + existing.getWord());
System.out.println("The current count is " + existing.getCount());
}
}
Class BookWord holds an implicit reference to a JavaApplication13 object. To make it not have such a reference, you should declare it static.
As it stands, BookWord is an inner class, to use official terminology. An inner class is one type of nested class. If you declare BookWord as static, then it's a static nested class. For explanations, see https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
This question already has answers here:
When does static initialization happen?
(3 answers)
Closed 6 years ago.
According to my knowledge whenever a class gets loaded an object of Class.class gets created for it by JVM, which stores all meta information of the loaded class.
When we use forName("classname") method, it first loads "classname" and then creates Class.class object for it and returns reference to the created Class.class object.
Example.java is given as:
class Example
{
static
{
System.out.println("Example Loaded");
}
Example()
{
System.out.println("Example Constructed");
}
}
Use.java is:
import java.lang.reflect.*;
class Use
{
int i;
public static void main(String[] args) throws Exception
{
Class c = Class.forName("Example");
Constructor[] con = c.getDeclaredConstructors();
for(Constructor x: con)
{
System.out.println(x.getName());
}
}
}
Running Use.java outputs:
Example Loaded
Example
getClass() is a method which can be used only with objects. So definitely before object creation a class will be loaded and object of Class.class will be created for it.
According to "Class and Data" section of http://www.onjava.com/pub/a/onjava/2005/01/26/classloading.html, "Whenever we compile any Java file, the compiler will embed a public, static, final field named class, of the type java.lang.Class, in the emitted byte code". We can use this field as:
import java.lang.reflect.*;
class Use
{
int i;
public static void main(String[] args) throws Exception
{
Class c = Example.class;
Constructor[] con = c.getDeclaredConstructors();
for(Constructor x: con)
{
System.out.println("Hello "+x.getName());
}
}
}
Output of above code is:
Hello Example
Static body of Example not get executed. Means the class Example did not get loaded.
My doubt is:
If class did not get loaded then object of Class.class also not get created for it. Then from where the statement "Class c = Example.class" returning the reference to Class.class?
There is a difference between class loading and class initialization.
A class can be loaded but not initialized. This is happening in case -2.
static initializers of a class are run when the class gets initialized and not when the class gets loaded.
Class.forName(String className) both loads and initializes the class. Hence in case 1, Example Loaded will be printed.
In case -2, since you are not doing anything to trigger the class initialization, Example Loaded will not be printed.
Also try Class c = Class.forName("Example", false, Sample.class.getClassLoader()); version of forName (which only loads the class but doesn't initialize it)and see what happens.
Just try to access a static field in class 2 (same code) and see what will happen.
class Example
{
static int i= 5;
static
{
System.out.println("Example Loaded");
}
Example()
{
System.out.println("Example Constructed");
}
}
public static void main(String[] args) {
Class c = Example.class;
Constructor[] con = c.getDeclaredConstructors();
for(Constructor x: con)
{
System.out.println("Hello "+x.getName());
}
System.out.println(Example.i);
}
Also you can check which classes are loaded but not initialized using java -verbose:class option.
As TheLostMind said "there is difference between class loading and class initialization. static initializers of a class are run when the class gets initialized and not when the class gets loaded".
Static members gets loaded in method area and so the field named "class".
But a class does not gets initialized for accessing a "static final" variable.
Example.java
class Example
{
static final int i = 5;
static
{
System.out.println("Example Loaded");
}
Example()
{
System.out.println("Example Constructed");
}
}
Use.java
import java.lang.reflect.*;
class Use
{
public static void main(String[] args) throws Exception
{
System.out.println(Example.i);
}
}
Running Use.class results
5
But if Example.i was
static int i = 5;
then running Use.class results as:
Example Loaded
5
Similar thing happens with field "class". As TheLostMind told "Class Objects are created in the JVM as classes are loaded". Field "class" initialized by compiler to point to object Class at compile time. So accessing Example.class we can access the class object. But accessing the field "class" does not make the class initialized, because this field is static and final.
I have followed Singleton:
public class GameConfig {
private static GameConfig mGameConfig = null;
private String mStr = "Boo";
public static GameConfig getInstance(){
if(mGameConfig == null){
mGameConfig = new GameConfig();
}
return mGameConfig;
}
private GameConfig(){}
public String getStr() {
return mStr;
}
}
Now I try to do some experiment:
Lets say I have other class User that goes to use this singelton:
public class User{
....
private void init(){
String str = GameConfig.getInstance().getStr();
}
}
So far so good.
I'll take above mentioned class User and add import static:
import static com.app.utils.GameConfig.getInstance; // no error, why??
public class User{
....
private void init(){
String str = GameConfig.getInstance().getStr();
// I can't type
// String str = getStr(); !!
// getInstance return instance
}
}
Why is there no error? Because that's valid syntax. Isn't it good for things to work?
import static com.app.utils.GameConfig.getInstance; // no error, why??
will make getInstance() available without naming the class, for instance:
GameConfig gc=getInstance();
As a side note, I'd rename the method to be more descriptive, like getGameConfig.
The Java Language specification has the answer. First, the definition of a member
A class body may contain declarations of members of the class, that
is, fields (§8.3), methods (§8.4), classes (§8.5), and interfaces
(§8.5).
A class body may also contain instance initializers (§8.6), static
initializers (§8.7), and declarations of constructors (§8.8) for the
class.
And the definition of a single static import
A single-static-import declaration imports all accessible static
members with a given simple name from a type. This makes these static
members available under their simple name in the class and interface
declarations of the compilation unit in which the single-static-import
declaration appears.
SingleStaticImportDeclaration:
import static TypeName . Identifier ;
The static method getInstance is a static member of the GameConfig class. You can therefore import it with
import static com.app.utils.GameConfig.getInstance;
If in the below
// I can't type
// String str = getStr(); !!
you meant for getStr() to be static method of GameConfig, it makes sense that it won't compile, since you haven't imported that member.
There is no error becuase the static import is valid. static imports allow to import the static content from a class. This allows to use the static variables/methods directly wihtout using the class name.
Also you cannot use getStr directly because that is not a static method.
Since it is a valid static import.So no error.
According to java static import
The static import construct allows unqualified access to static members without inheriting from the type containing the static members. Instead, the program imports the members, either individually. at
Here getInstance() is static member so it is valid import statement.
I was told that static methods in java didn't have Inheritance but when I try the following test
package test1;
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
TB.ttt();
TB.ttt2();
}
}
package test1;
public class TA {
static public Boolean ttt()
{
System.out.println("TestInheritenceA");
return true;
}
static public String test ="ClassA";
}
package test1;
public class TB extends TA{
static public void ttt2(){
System.out.println(test);
}
}
it printed :
TestInheritenceA
ClassA
so do java static methods (and fields) have inheritance (if you try to call a class method does it go along the inheritance chain looking for class methods). Was this ever not the case? And are there any inheritance OO languages that are messed up like that for class methods?
So apparently static methods are inherited but can't be overidden, so does c# share that problem? Do any other Languages?
In Java, fields and static methods are inherited, but cannot be overridden - I believe that is what whoever told you that "they are not inherited" meant.
Non-private, non-static methods are inherited and can be overridden.
This was always the case, but you cannot override class methods:
class A {
public static void a() { system.out.println("A"); }
}
class B {
public static void a() { system.out.println("B"); }
}
A a = new A();
a.a(); // "A"
B b = new B();
b.a() // "B"
a = b;
a.a(); // "A"
That's the meaning of static. It means per class. Static fields and methods are shared among instances. If you change a static value, it's reflected across instances.