What does this single static method do? - java

I'm unsure what this does, I haven't seen it before and can't find any information about it.
private static String[] names = { "A.ttf" };
private static Map<String, Font> cache = new ConcurrentHashMap<String, Font>(names.length);
static {
for (String name : names) {
cache.put(name, getFont(name));
}
}

That is not a static method but a static block.
Static blocks are executed first(in same order they are declared) when class gets loaded and usually used for initializing things.
in your case it puts all names in "names" to cache.
refer this or an answer on SO for more info

A block is denoted by {\\some code}. A placed static keyword denotes that it is a static block. static block is known as Static Initializers and non static block is known as Instance Initializers.
None of them can contain return statement.
The non-static block will be called every time you are creating a new instance and it will be called/executed just before the Constructor. The static block will be called/executed only once and it will be the first time your are accessing the class.
Example:
class A {
static{ // static
System.out.println("Static block of Class A");
}
{ // non-static
System.out.println("Non-Static block of a instance of Class A");
}
public A(){
System.out.println("Constructing object of type A");
}
}
public class StaticTest {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
}
}
Output:
static block of Class A
Non-Static block of a instance of Class A
Constructing object of type A
Non-Static block of a instance of Class A
Constructing object of type A

Related

Why static block is not executed

As per java doc, static block is executed when the class is initialized.
Could anyone please tell me why static block is not executed when I run below code?
class A {
static {
System.out.println("Static Block");
}
}
public class Main {
public static void example1() {
Class<?> class1 = A.class;
System.out.println(class1);
}
public static void example2() {
try {
Class<?> class1 = Class.forName("ClassLoading_Interview_Example.ex1.A");
System.out.println(class1);
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
example1();
}
}
A class's static initialization normally happens immediately before
the first time one of the following events occur:
an instance of the class is created,
a static method of the class is invoked,
a static field of the class is assigned,
a non-constant static field is used, or [...]
You are currently not doing any of the above.
So, by replacing
Class<?> class1 = A.class;
System.out.println(class1);
with this for example
A object = new A();
will give you your result.
Referencing A.class will not resulting in executing A's static initializers, see here
Initialization of a class consists of executing its static
initializers and the initializers for static fields (class variables)
declared in the class.
And
A class or interface type T will be initialized immediately before the
first occurrence of any one of the following:
T is a class and an instance of T is created.
A static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant
variable (§4.12.4).

static block inside static inner class

we know that a static block in java is resovled while compliling, not at runtime. Hence again We know that a static inner class is instantiated during the first call to the nested class.
Now suppose the nested class is having a static block. So, in that case can we say that static block inside the nested class will be resolved when the first attempt to access that nested class is made?
Sample code:
public class A
{
public static class B
{
static A a;
static
{
a=new A();
}
public static A getA()
{
return a;
}
}
}
Now I am accessing as:
A a= A.b.getInstance();
I hope at that point only static block in B will be executed and not before that.
This should answer your question:
public class Test {
public Test() {
System.out.println("Test instantiated");
}
public static class Inner {
static {
System.out.println("Static block executed");
}
public Inner() {
System.out.println("Test.Inner instantiated");
}
}
}
When calling:
Test test = new Test();
Test.Inner inner = new Test.Inner();
We get:
Test instantiated
Static block executed
Test.Inner instantiated
static block in java is resovled while compliling
No it isn't.
All static code is resolved once by the classloader, when loaded/initalized.
From jls Compile time error will happen from static blocks only when
If a static initializer cannot complete normally.
If a return statement appears anywhere within a static initializer.
If the keyword this or the keyword super or any type variable declared outside the static initializer, appears anywhere within a static initializer.
static block will be executed when the class is initialized, so in your example, the static block inside your static class B will get executed first.

Java - Anonymous class are static or not

I know it depends on the context in which the anonymous class has been written (static or non static method).
but look this part of code:
public class A {
int fieldOfA;
private static class B {
int fieldOfB;
}
public static void main(String[] args) {
B obj = new B() { //this anonymous class is static becuase is in the main method.
private static void testMethod() { //so why here i have an error and i can put just a non-static method
//if my class is static ?
//a class static can have static method, but this class no, why?
}
};
}
}
it's sure that anonymous class are static?
An anonymous class is static if the context is static. e.g. in a static method.
An anonymous class is non static if there is a non static context, whether you need it to be non-static or not. The compiler is not smart enough to make a class static if the non static context is not used.
In this example, two anonymous classes were created. One in a static method has no reference to an outer class and is like a static nested class.
Note: these classes are still called "Inner" and cannot have static members even though they have no reference to an Outer class.
import java.util.Arrays;
public class Main {
Object o = new Object() {
{
Object m = Main.this; // o has a reference to an outer class.
}
};
static Object O = new Object() {
// no reference to Main.this;
// doesn't compile if you use Math.this
};
public void nonStaticMethod() {
Object o = new Object() {
{
Object m = Main.this; // o has a reference to an outer class.
}
};
printFields("Anonymous class in nonStaticMethod", o);
}
public static void staticMethod() {
Object o = new Object() {
// no reference to Main.this;
// doesn't compile if you use Math.this
};
printFields("Anonymous class in staticMethod", o);
}
private static void printFields(String s, Object o) {
System.out.println(s + " has fields " + Arrays.toString(o.getClass().getDeclaredFields()));
}
public static void main(String... ignored) {
printFields("Non static field ", new Main().o);
printFields("static field ", Main.O);
new Main().nonStaticMethod();
Main.staticMethod();
}
}
prints
Non static field has fields [final Main Main$1.this$0]
static field has fields []
Anonymous class in nonStaticMethod has fields [final Main Main$3.this$0]
Anonymous class in staticMethod has fields []
From JLS 15.9.5:
An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1).
Section 8.1.3 talks more about inner classes, including when they occur in a static context. But they're never static themselves, and thus can't declare static members (other than constant variables).

can we have static block in non static class in java?

I have few question about static in java
Can we have static block in non static class??If an object of
that(no-static) class is initialized in some other class,will the
static block get executed then??
If there is a static class having static block and variable( int a =
3) and main() method,and it is executed then will the variable
initialization take place first or static block execution?I know
that static block gets executed before the main() method.
1) No, you cant, try this
class Test1 {
class X {
static { <-- compile error: Cannot define static initializer in inner type Test1.X
}
}
...
X should be static.
Note: I assume we are talking about nested classes, because this is where static modifier is applicable for classes
2) it depends, see this
class Test1 {
static {
x = 3;
}
static int x = 2;
public static void main(String[] args) throws Exception {
System.out.println(x);
}
}
output
2
but now
class Test1 {
static int x = 2;
static {
x = 3;
}
public static void main(String[] args) throws Exception {
System.out.println(x);
}
}
output will be
3
Static initialization runs only ones during class loading, it happens always before any instance instantiation. Interestingly both static fields initialization and static init block code runs in the same bytecode function with the name <clinit>:
static <clinit>()V
L0
LINENUMBER 12 L0
ICONST_3
PUTSTATIC test/Test1.x : I
L1
LINENUMBER 15 L1
ICONST_2
PUTSTATIC test/Test1.x : I
RETURN
Please look here http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
It's called static initializer in the spec. This code will be executed when JVM loads the class. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.
You can't use static code in nonstatic inner classes:
public class MyClass {
static {
System.out.println("static code from nonstatic class");
}
class In {
/* it will not compile
static {
}
*/
}
static class In2 {
static {
System.out.println("static code from static inner class");
}
}
public static void main(String[] args) {
MyClass c = new MyClass();
}
}
See Detailed Initialization Procedure in The Java® Language Specification for details about calling order. Simply the static blocks are executed in the order they appear in the source code.
Having a static class vs. a normal class does not affect what programming constructs you are allowed to use, but simply controls whether or not the class has access to instance fields/methods of the surrounding class.
Yes we can have a static block in a non-static class and it is loaded as soon as class loads in JVM
public class StaticDemo {
static{
System.out.println("already loaded");
}
public static void main(String [] args){
}
}
This outputs already loaded
For question 2, the answer can be found in the Java Language Specification §12.4.2, in particular step 9 of the "detailed initialization procedure":
Next, execute [...] the class variable initializers and static initializers of the class [...] in textual order, as though they were a single block.
In other words, the static {} blocks and the initializer expressions of static fields are executed in the order they appear in the source code - if the static block is before the field declaration then it will run first (and see the default value of the field, typically null or 0), if the static block is after the field declaration then it will run second (and will see the value assigned by the initializer expression).

Accessing non-static members through the main method in Java

As a rule in object-oriented paradigm, a static method can have access only to static variables and static methods. If it is so, an obvious question arises as to how can the main() method in Java has access to non-static members (variables or methods) even though it is specifically public static void...!!!
The main method does not have access to non-static members either.
public class Snippet
{
private String instanceVariable;
private static String staticVariable;
public String instanceMethod()
{
return "instance";
}
public static String staticMethod()
{
return "static";
}
public static void main(String[] args)
{
System.out.println(staticVariable); // ok
System.out.println(Snippet.staticMethod()); // ok
System.out.println(new Snippet().instanceMethod()); // ok
System.out.println(new Snippet().instanceVariable); // ok
System.out.println(Snippet.instanceMethod()); // wrong
System.out.println(instanceVariable); // wrong
}
}
By creating an object of that class.
public class Test {
int x;
public static void main(String[] args) {
Test t = new Test();
t.x = 5;
}
}
The main() method cannot have access to the non-static variables and methods, you will get “non-static method cannot be referenced from a static context” when you try to do so.
This is because by default when you call/access a method or variable it is really accessing the this.method() or this.variable. But in the main() method or any other static method(), no "this" objects has yet been created.
In this sense, the static method is not a part of the object instance of the class that contains it. This is the idea behind utility classes.
To call any non-static method or variable in a static context, you need to first construct the object with a constructor or a factory like your would anywhere outside of the class.
YourClass inst = new YourClass();
inst.nonStaticMethod();
inst.nonStaticField = 5;
You have to instantiate the object you wish to access.
For example
public class MyClass{
private String myData = "data";
public String getData(){
return myData;
}
public static void main(String[] args){
MyClass obj = new MyClass();
System.out.println(obj.getData());
}
}
Through the reference to the object.
public class A {
private String field;
public static void main(String... args) {
//System.out.println(field); <-- can not do this
A a = new A();
System.out.println(a.field); //<-- access instance var field that belongs to the instance a
}
}
You must create an instance of the class in order to reference instance variables & methods.

Categories

Resources