Are classes in Java `static` or `non-static`? - java

Are classes in Java static or non-static?

Static applies only to blocks, methods and class member variables. There's no meaning in having a Class Static, although an inner class can be static member of its enclosing class. Refer nested classes.

Classes are not static. only inner classes can be marked as static
public class NotStatic
{
static class StaticClass
{
}
}
That is the only type that can be static.
Edit:
public class NotAStaticClass
{
private static int foo;
public static int getFoo()
{ return foo; }
}
How will you statically instantiate this class? Answer, you cannot. You must still utilize the new operator.
NotAStaticClass s1 = new NotAStaticClass();

Were you perhaps asking if Java is a statically typed language? If so, then the answer is yes. See Wikipedia on Static Typing

Are you taking about Static inner classes or Static Methods or Static Variables ?
As Best practice avoid using static in following cases
Avoid using Static in MultiThreaded Env.
Avoid having Static methods in your Business logic layer, if not you may lose the
advantages of OOPs such as inheritance, runtime polymorphism.

Concept of something being static is to get initialized only once i.e have only one copy in memory.. The same copy can be used whenever we want without creating another copy in memory again. So Classes being templates are not static ...

Classes cannot be static. Only methods, blocks, and variables within a class can be static, but not the class itself.

Related

Java convention on reference to methods and variables

Section 10.2 of Java conventions recommends using class names instead of objects to use static variables or methods, i.e. MyClass.variable1 or MyClass.methodName1() instead of
MyClass Obj1 = new MyClass();
Obj1.variable1;
Obj1.methodName1();
There is no explanation of the rationale behind this, although I suspect this has something to do with memory use. It would be great if someone could explain this.
I guess you mean "for static methods and variables".
There is no difference regarding memory, except of course if you create the instance just for calling the method. Conventions aren't for memory efficiency but for coder efficiency, which is directly related with the readability of the code.
The rationale is that by reading
MyClass.methodName1()
you know it's a static method and that it can't use or change your Obj1 instance.
And if you write
obj1.variable1; // note the "o" instead of "O", please do follow conventions
then the reader has to read your source code to know if variable1 is static or not.
If you use object for static variable access then compiler will replace it with Class Name only.
So
MyClass Obj1 = new MyClass();
Obj1.variable1;
Obj1.methodName1();
It is same as
MyClass.variable1;
MyClass.methodName1();
Now Why to differentiate? Answer is - It is for better reading If someone see method being called on Class then he immediately come to know that it is static method. Also it prevents generation of one additional object to access the method.
This has to do with public static methods and variables. Since these methods/variables are associated with the respective class rather than an instance of the class, it is nice to use refer to these methods or variables as className.methodName() or className.variableName
"Understanding Instance and Class Members" would be a good starting point to learn about the use of the static keyword to create fields and methods that belong to the class, rather than to an instance of the class
It is only because, public static method or public static variable is not associated with any object, but the class. Though the language designer has given the flexibility of invoking them on objects, reader of the code would be confused whether those are static variable/methods or instance methods/variables. So readability is the reason behind asking the developers to invoke them on classes.
You are allowed to access static members either by using the class name notation or by accessing using an object. It is not recommended to use the object notation since it can be very confusing.
public class TheClass {
public static final staticValue = 10;
public static void staticMethod() {
System.out.println("Hello from static method");
}
public static void main(String ... args) {
TheClass obj = null;
// This is valid
System.out.println(obj.staticValue);
// And this too
System.out.println(obj.staticMethod());
// And this is also valid
System.out.println(((TheClass)null).staticValue);
// And this too
System.out.println(((TheClass)null).staticMethod());
}
}
It is much clearer if the static methods and variables are called with the class name notation.
static variable belongs to the class and not to object(instance).
A static variable can be accessed directly by the class name and doesn’t need any object.
it saves space not having to have variables for the same data for each class.
Syntax : <class-name>.<variable-name>
public class AA{
static int a =10;
}
You can call
System.out.println(AA.a);
System.out.println(aObject.a);
There is no differen between two calling but maintain coding convention to keep more readbale

static class in java

How do I declare a static class in java? eclipse wants me to remove "static" from the declaration.
static public class Constants {
First to answer your question:
Only a Nested class can be declared static. A top level class cannot declared be static.
Secondly, Inner class is a nested class that is not explicitly declared static. See the java language spec. So contrary to some answers here, Inner classes cannot be static
To quote an example from the spec:
class HasStatic{
static int j = 100;
}
class Outer{
class Inner extends HasStatic{
static final int x = 3; // ok - compile-time constant
static int y = 4; // compile-time error, an inner class
}
static class NestedButNotInner{
static int z = 5; // ok, not an inner class
}
interface NeverInner{} // interfaces are never inner
}
If by 'static' you mean 'can have only static members', there's no such thing in Java.
Inner classes (and only them) can be static, but that's a different concept. Inner static classes can still have instance members.
Eclipse complains correctly, your code won't compile as Top level class can't be declared as static.
You need to first understand what static class means.
static class :
Top level class can't be declared as static. Only Member and Nested top-level classes can be defined as static.
You declare member classes when you want to use variables and methods of the containing class without explicit delegation. When you declare a member class, you can instantiate that member class only within the context of an object of the outer class in which this member class is declared. If you want to remove this restriction, you declare the member class a static class.When you declare a member class with a static modifier, it becomes a nested top-level class and can be used as a normal top-level class as explained above.
nested top-level class is a member classes with a static modifier. A nested top-level class is just like any other top-level class except that it is declared within another class or interface. Nested top-level classes are typically used as a convenient way to group related classes without creating a new package.
Also check when should we go for static class,variables and methods in java
As you have already been told from the other comments, classes cannot be declared static. However there are alternatives to this problem.
The most simple one is to precede all member variables and methods with the static modifier. This essentially does what you want.
A slightly more involved alternative is to make the class a singleton. This is a class in which through the use of a private constructor, and an instanceOf() method, or just an Enum, you can only have one instance of that class. Semantically and syntactically you treat that instance as an ordinary instance of whatever particular class you are making a singleton, but you can only have a single instance of that class, which you retrieve via SomeObject.instanceOf(), or in an Enum implementation, SomeObject.INSTANCE.
You would normally use Enums to implement this, minus the edge cases where you are extending another class.
For more complete information on singletons visit the link below.
Design Patterns in Java - Singleton
There is no direct equivalent of C# static classes in Java, but the closest thing in my opinion is an empty enum, which might seem weird at first, but makes sense the more you think about it. An enum in Java (unlike in C#) is essentially a set of singleton instances that all implement the same abstract base class and interfaces. The quickest and safest way to make a normal singleton in Java is like so:
enum Foo {
INSTANCE;
public Bar doSomething(Baz baz) {
return Bar.fromBaz(baz); // yadda yadda
}
}
So since we are dealing with sets of singletons, it make sense that we can have an empty set. And an empty set means there can be no instances. This is conceptually the same as a static class in C#.
enum MyUtilities {
;
static Bar doSomething(Baz baz) {
return Bar.fromBaz(baz); // yadda yadda
}
static final String SOME_CONSTANT = "QUX";
}
This is great because you won't lose test coverage because of hard to test private constructors in a final class, and the code is cleaner than a final class with an empty private constructor.
Now, if the static classes are meant to all work on a single Interface and you have control of that Interface, then you should implement the static methods on that Interface itself (something you can't do in C#).
All top level classes are implicitly static, meaning they can be accessed by everybody. So it makes sense only to make inner classes optionally static.

java objects, shared variables

I have a simple question here.
If I declare a variable inside an object which was made [declared] in the main class, like this:
public static int number;
(
usually I declare it like this :
private int number;
)
can it be used in a different object which was also made [declared] in the main class?
btw I do not care about security atm, I just want to make something work, don't care about protection)
Here's a telling quote from Java Language Specification:
JLS 8.3.1.1 static Fields
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized.
A field that is not declared static (sometimes called a non-static field) is called an instance variable. Whenever a new instance of a class is created, a new variable associated with that instance is created for every instance variable declared in that class or any of its superclasses.
[Example program follows...]
In short, a static field is a class variable: it belongs to the class, as opposed to the instances of the class. In a way, you can think of a static field as a variable shared by instances of the class, but it's much more consistent to think of static fields as belonging to the class, just like static method also belongs to the class, etc.
Since they belong to the class, they do not require an instance of said class to access (assuming adequate visibility), and in fact it's considered bad programming practice to access static members through an instance instead of a type expression.
Related questions
Java - static methods best practices
Static methods
calling non-static method in static method in Java
non-static variable cannot be referenced from a static context (java)
When NOT to use the static keyword in Java?
Static variables and methods
If the class holding 'number' is called MyClass
you can refer to it as MyClass.number from any method.
Doing so for a variable is not good design though.
There are really two issues here: public vs. private in the context of inner classes, and static variables.
Part 1:
static means that you don't need an instance of the class to access that variable. Suppose you have some code like:
class MyClass {
public static String message = "Hello, World!";
}
You can access the property this way:
System.out.println(MyClass.message);
If you remove the static keyword, you would instead do:
System.out.println(new MyClass().message);
You are accessing the property in the context of an instance, which is a copy of the class created by the new keyword.
Part 2:
If you define two classes in the same java file, one of them must be an inner class. An inner class can have a static keyword, just like a property. If static, it can be used separately. If not-static, it can only be used in the context of a class instance.
Ex:
class MyClass {
public static class InnerClass {
}
}
Then you can do:
new MyClass.InnerClass();
Without the 'static', you would need:
new MyClass().new InnerClass(); //I think
If an inner class is static, it can only access static properties from the outer class. If the inner class is non-static, it can access any property. An inner class doesn't respect the rules of public, protected, or private. So the following is legal:
class MyClass {
private String message;
private class InnerClass {
public InnerClass() {
System.out.println(message);
}
}
}
If the inner class has keyword static, this would not work, since message is not static.
static variables are shared by all instances of a given class. If it's public, it is visible to everything.
non-static variables belong to only one instance.
Since your main method is static, it can only see static variables. But you should avoid working statically - make an instance of a class, and pass the data around as method/constructor parameters, rather than sharing it via static variables.

Are static anonymous classes definitely wrong in Java?

I've read elsewhere that a static anonymous class doesn't make sense - that all anonymous classes should be tied to an instance of the enclosing type. But the compiler let's you do it. Here's an example:
class Test {
/*
* What's the difference at between
* Test.likeThis and Test.likeThat?
*/
// This is obviously okay:
private static final class LikeThat {
#Override
public String toString() { return "hello!"; }
}
public static Object likeThat = new LikeThat();
// What about this - is it really any different?
public static Object likeThis = new Object() {
#Override
public String toString() { return "hello!"; }
};
}
What's going on here?
From the Java Language Specification, section 8.1.3:
An instance of an inner class I whose declaration occurs in a static context has no lexically enclosing instances. However, if I is immediately declared within a static method or static initializer then I does have an enclosing block, which is the innermost block statement lexically enclosing the declaration of I.
Your anonymous class (the one likeThis is an instance of) occurs in a static context, so it is not tied to an enclosing instance. However, it seems that it can refer to final variables of its enclosing block (see the rest of section 8.1.3, they give an example).
Btw, your wording is a bit deceptive, you're actually referring to a static instance of an anonymous class (it's the instance that's static, not the class).
I see nothing wrong with static anonymous classes
Like anything in any language you should just consider why you're doing it. If you've got alot of these instances then I'd question the design decisions, but it doesn't necessarily means it's a pattern that should never be followed.
And of course, always consider the testability of the class and whether you can provide a test double if the need arises
I don't think they have no sense. If you don't need reference to enclosing object then it's better to leave it static. Later it can evolve in separate class with ease.
Wide-spread enum idiom (pre Java 5) used similar approach with anonymous static inheritors of enum class. Probably, now it is better stick to Java 5 enum for this case.
If you are able to find adequate real-world application for anonymous static classes - why not to use them?
I do this all the time. It's especially handy for special-case implementations of utility interfaces, e.g.:
/** A holder for {#link Thing}s. */
public interface ThingsHolder {
/** A {#link ThingsHolder} with nothing in it. */
public static final ThingsHolder EMPTY_HOLDER = new ThingsHolder() {
#Override
public Iterable<Thing> getThings() {
return Collections.emptySet();
}
};
/** Provides some things. */
Iterable<Thing> getThings();
}
You could create a private static inner class called EmptyHolder, and maybe in some cases that would make the code more readable, but there's no reason you have to do it.
According to this answer which references the JLS, anonymous classes are never static, but when created in a "static context" they have no "enclosing instance".
That said,
They give the same error at compile time if you try to reference Test.this (non-static variable this cannot be referenced from a static context)
At runtime, the only obvious difference between the Class objects (apart from name) is that Test$1 is an "anonymous class" and Test$LikeThat is a "member class". Both of them have an enclosing class; neither of them have an enclosing constructor or method. (I only checked the likely-looking methods; there may be other differences.)
EDIT: According to getModifiers(), Test$1 is static and Test$LikeThat is static final! According to the language spec, Test$1 should actually be final. Hmm...
According to javap -c -verbose -s -private -l,
Test$1 specifies an "EnclosingMethod" (probably Test's static initializer?)
Test$LikeThat has an extra entry under "InnerClass" (#12; //class Test$1) and a curious constructor Test$LikeThat(Test$1). This appears to happen because LikeThat is private which makes the constructor private, so the compiler generates a "trampoline" to allow it to be called from Test.
If you remove the private, they appear to compile to roughly the same thing apart from the EnclosingMethod entry.
Test$1 does not have the field final Test this$0; that it would if it was defined in a non-static context.
Seems perfectly legitimate to me. Since the anonymous class is static it won't have a reference to any enclosing class, but there should be no evil consequences from that.
Well, other than being a hidden singleton object, that's pretty evil.
Of course they are not. I always use static nested classes, unless I need the implicit association to the enclosing object.
In java terminology nested class := a class which is declared within another class (or interface). Inner classes are those nested classes which have an associated instance from the enclosing class. (Nonstatic member classes, local classes, anonymous classes).
The implicit association can prevent garbage collection sometimes.
These can be very convenient because of possibility to make circular references:
class A
{
public static final A _1 = new A() {
public A foo()
{
return _2;
}
};
public static final A _2 = new A() {
public A foo()
{
return _1;
}
};
}
Creation of several objects which are holding references to each other can be very awkward without usage of anonymous classes.

Why does Java prohibit static fields in inner classes?

class OuterClass {
class InnerClass {
static int i = 100; // compile error
static void f() { } // compile error
}
}
Although it's not possible to access the static field with OuterClass.InnerClass.i, if I want to record something that should be static, e.g. the number of InnerClass objects created, it would be helpful to make that field static. So why does Java prohibit static fields/methods in inner classes?
EDIT: I know how to make the compiler happy with static nested class (or static inner class), but what I want to know is why java forbids static fields/methods inside inner classes (or ordinary inner class) from both the language design and implementation aspects, if someone knows more about it.
what I want to know is why java forbids static fields/methods inside inner classes
Because those inner classes are "instance" inner classes. That is, they are like an instance attribute of the enclosing object.
Since they're "instance" classes, it doesn't make any sense to allow static features, for static is meant to work without an instance in the first place.
It's like you try to create a static/instance attribute at the same time.
Take the following example:
class Employee {
public String name;
}
If you create two instances of employee:
Employee a = new Employee();
a.name = "Oscar";
Employee b = new Employee();
b.name = "jcyang";
It is clear why each one has its own value for the property name, right?
The same happens with the inner class; each inner class instance is independent of the other inner class instance.
So if you attempt to create a counter class attribute, there is no way to share that value across two different instances.
class Employee {
public String name;
class InnerData {
static count; // ??? count of which ? a or b?
}
}
When you create the instance a and b in the example above, what would be a correct value for the static variable count? It is not possible to determine it, because the existence of the InnerData class depends completely on each of the enclosing objects.
That's why, when the class is declared as static, it doesn't need anymore a living instance, to live itself. Now that there is no dependency, you may freely declare a static attribute.
I think this sounds reiterative but if you think about the differences between instance vs. class attributes, it will make sense.
The idea behind inner classes is to operate in the context of the enclosing instance. Somehow, allowing static variables and methods contradicts this motivation?
8.1.2 Inner Classes and Enclosing Instances
An inner class is a nested class that is not explicitly or implicitly declared static. Inner classes may not declare static initializers (§8.7) or member interfaces. Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).
InnerClass cannot have static members because it belongs to an instance (of OuterClass). If you declare InnerClass as static to detach it from the instance, your code will compile.
class OuterClass {
static class InnerClass {
static int i = 100; // no compile error
static void f() { } // no compile error
}
}
BTW: You'll still be able to create instances of InnerClass. static in this context allows that to happen without an enclosing instance of OuterClass.
From Java 16 onwards, this is no longer the case. Quoting from JEP 395 (on finalizing records):
Relax the longstanding restriction whereby an inner class cannot declare a member that is explicitly or implicitly static. This will become legal and, in particular, will allow an inner class to declare a member that is a record class.
Indeed, the following code can be compiled with Java 16 (tried with 16.ea.27):
public class NestingClasses {
public class NestedClass {
static final String CONSTANT = new String(
"DOES NOT COMPILE WITH JAVA <16");
static String constant() {
return CONSTANT;
}
}
}
Actually, you can declare static fields if they are constants and are written in compile time.
class OuterClass {
void foo() {
class Inner{
static final int a = 5; // fine
static final String s = "hello"; // fine
static final Object o = new Object(); // compile error, because cannot be written during compilation
}
}
}
class Initialization sequence is a critical reason.
As inner classes are dependent on the instance of enclosing/Outer class, so Outer class need to be initialized before the initialization of the Inner class.
This is JLS says about class Initialization. The point we need is, class T will be initialize if
A static field declared by T is used and the field is not a constant variable.
So if inner class have an static field accessing that will cause initializing the inner class, but that will not ensure that the enclosing class is initialized.
It would violate some basic rules. you can skip to the last section (to two cases) to avoid noob stuff
One thing about static nested class, when some nested class is static it will behave just like a normal class in every way and it is associated with the Outer class.
But the concept of Inner class/ non-static nested class is it will be associated with the instance of outer/enclosing class. Please note associated with instance not the class.
Now associating with instance clearly means that (from the concept of instance variable) it will exist inside a instance and will be different among instances.
Now, when we make something static we expect it will be initialized when the class is being loaded and should be shared among all instances. But for being non-static, even inner classes themselves (you can definitely forget about instance of inner class for now) are not shared with all instance of the outer/enclosing class (at least conceptually), then how can we expect that some variable of inner class will be shared among all the instance of the inner class.
So if Java allow us to use static variable inside not static nested class. there will be two cases.
If it is shared with all the instance of inner class it will violate the concept of context of instance(instance variable). It's a NO then.
If it is not shared with all instance it will violate the the concept of being static. Again NO.
Here is the motivation that I find best suitable for this "limit":
You can implement the behavior of a static field of an inner class as an instance field of the outer object;
So you do not need static fields/methods.
The behaviour I mean is that all inner class instances of some object share a field(or method).
So, suppose you wanted to count all the inner class instances, you would do:
public class Outer{
int nofInner; //this will count the inner class
//instances of this (Outer)object
//(you know, they "belong" to an object)
static int totalNofInner; //this will count all
//inner class instances of all Outer objects
class Inner {
public Inner(){
nofInner++;
totalNofInner++;
}
}
}
In simple words, non-static inner classes are instance variable for outer class, and they are created only when an outer class is created and an outer class object is created at run-time while static variables are created at class loading time.
So non-static inner class is runtime thing that's why static not the part of a non-static inner class.
NOTE: treat inner classes always like a variable for an outer class they may be static or non-static like any other variables.
Because it would cause ambiguity in the meaning of "static".
Inner classes cannot declare static members other than
compile-time constants. There would be an ambiguity about the meaning
of “static.” Does it mean there is only one instance in the virtual
machine? Or only one instance per outer object? The language designers
decided not to tackle this issue.
Taken from "Core Java SE 9 for the Impatient" by Cay S. Horstmann. Pg 90 Chapter 2.6.3
In the Java language designers' own words:
Since nested classes were first introduced to Java, nested class
declarations that are inner have been prohibited from declaring static
members... It simplifies the language's task of resolving and
validating references to in-scope variables, methods, etc.
There was never any particularly grand conceptual or philosophical reason to prohibit this.
Simplifying things for the language was deemed an insufficient reason to continue to maintain this restriction. Along with the introduction of records in Java 16, they made the decision to relax the restriction.
Class Inner will be initialize if a static field declared by Inner is used and the field is not a constant variable.
class Outer{
class Inner{
static Inner obj = new Inner();
}
public static void main(String[] args){
Inner i = Inner.obj; // It woulds violate the basic rule: without existing Outer class Object there is no chance of existing Inner class Object.
}
}
I guess it's for consistency. While there doesn't seem to be any technical limitation for it, you wouldn't be able to access static members of the internal class from the outside, i.e. OuterClass.InnerClass.i because the middle step is not static.

Categories

Resources