Actually this is a three part question.
1 I want know to know on what occasions do we use the keyword class. It is obvious that we use it to
define a class. But what is the purpose of using SomeClass.class in a expression?
2 I read on Wikipedia that it can be used instead of the expression new SomeClass().getClass(). But why do we need this when we already can use new SomeClass().getClass() expression?
3 And when do we need to use this SomeClass.class expression in a statement?
I am referring to Anonymous Inner classes and it occurred to me we can't use the getClass() method in a static method.
The following answer from Stephen gives the exact unique answer for this problem.
But what is the purpose of using SomeClass.class in a expression?
It is called a class literal; see JLS 15.8.2.
The purpose is to get the Class object that for the class denoted by SomeClass. (But you already knew that ...)
But why do we need this when we already can use new SomeClass().getClass() expression?
Because new SomeClass() creates a new instance of SomeClass():
This is unnecessary
It may be expensive
It may have unwanted side-effects
It may be necessary to supply multiple arguments
It may not even be possible; e.g. if the constructors are not accessible, or the class is abstract.
And when do we need to use this SomeClass.class expression in a statement?
There are numerous use-cases involving reflection where you need the Class object for a class to do things. Start by reading a good tutorial on Java reflection.
I am referring to Anonymous Inner classes
A class literal can't be used to get the Class of an anonymous inner class. But this.getClass() will work in any instance1 method of an anonymous class.
... it occurred to me we can't use the getClass() method in a static method.
Well, I guess that would be a scenario where you need a class literal.
But strictly speaking you can call getClass() in a static method. The problem is that you can't call it on this, either explicitly or implicitly.
1 - I can't think of a convincing use-case for a static method in an anonymous class. It would only be possible to refer to such a method outside of the anonymous class by using reflection. So it may as well be declared as an instance method.
Related
If you search 'java double brace' you'll find strong arguments against using it.
Every time someone uses double brace initialisation, a kitten gets killed.
https://stackoverflow.com/a/27521360/555631
The arguments are you're creating way too many anonymous classes and you're potentially creating a memory leak.
Are lambdas any different? They each create an anonymous inner class, they each reference their enclosing closure.
Lambda expressions are different from an anonymous inner class that happens to implement a functional interface.
Anonymous inner classes will create their own class file at compilation, usually something along the lines of Foo$1.class, if it's contained in the Foo class. It is a fully functional class that implements an interface or subclasses a class. To reference local values outside its scope, it will, behind the scenes, create an instance variable in the anonymous inner class that represents a copy of the value. This is why the variable must be effectively final -- otherwise the actual variable may change and the copy may be stale.
Lambda expressions don't create anonymous inner classes. They use a java.lang.invoke.LambdaMetafactory that produces a CallSite that can be used later to execute the lambda expression. The lambda expression, whether it's a block or an expression, gets converted to a hidden private static method within the class in which it's contained. Instead of creating a class with a hidden variable, captured values get translated into parameters of the hidden private static method. Local values still must be effectively final because the value passed to the method is again a copy. The method gets invoked by a invokedynamic instruction in the JVM.
Sources:
How Lambdas And Anonymous Inner Classes Work
PART 4 – HOW LAMBDA EXPRESSION INTERNALLY WORKS
Yes, they are different.
Lambdas don't actually necessarily create anonymous classes -- they're certainly not just translated into the equivalent anonymous class. Their creation is much more convoluted than that, and often ends up with an anonymous class created at runtime, but not necessarily.
Lambdas specifically do not capture anything except the variables specifically mentioned in them, unlike anonymous inner classes, which do capture the enclosing class object if they're defined in an instance method.
We use System.out.println without instantiating it or creating object of it. Same goes to Math class and many others (I guess). Is there something special about these classes? Can we use the classes and methods declared within those classes in same fashion? Please help.
You don't have to create objects for the System and Math classes because the methods and variables in those classes are static. This means that they belong to the class itself, not to instances of the class.
For reference see:
Understanding Class Members
Beyond Basic Arithmetic
This is something called 'static' method. In order to invoke static method, you do not need to have an instance of the class.
This also has other side effects such as non-existing 'this' and thus static methods cannot invoke instance methods.
This is mostly used for some sort of utility classes which are often stateless.
Math is a good example for it.
I suggest to read a bit about static methods and static in Java in general.
You don’t need to create object of System and Math class to use it because they have static methods. Static methods belong to the class and thus doesn’t require it to be instantiated.
Although, you can create its object and then also use those methods, but creating a class for static method is of no use.
Why don't we have to create object of System or Math classes in java and use them directly?
Because the methods of Math are declared as static methods, and because System.in / System.out / System.err are static variables.
Is there something special about these classes?
No. Any variables or methods that are declared as static will behave that way.
Can we use the classes and methods declared within those classes in same fashion?
I don't really understand what you are asking there. But, if you are asking if you can create an instance of Math or System so that you can do something like this:
Math myMath = new Math();
myMath.min(1, 2);
No, you can't. Neither of those classes has a public constructor, so you can't new them.
And if you could do that, it would be really bad style!
Reference:
Understanding Class Members
First,you cannot make an instance of the class Math,because it has only a single constructor and it's been marked private and you just can't make an instance of it from outside the class.
Snapshot of the source code of the class Math
Second,you don't need to do that.All of the methods in class Math are static,just use the class name and the dot operator and you can invoke any one of them.
System class can't instantiate/create object because this System class have private constructor.
And it's all members and methods are static, that can be accessible directly by Class name.
this simple and valid answer will help you.
We don't instantiate every other class or method because the JVM(Java Virtual Machine) already loads them into the project and hence, we can use these classes again and again. One such example is the main method. These classes/methods are already predefined for us so there is no need for us to instantiate such classes/methods because they are static.
You don't have to instantiate the object in order to use methods of the math class.
Because to use this methods we don't need object. We can directly invoke this.
These type of classes are called static. Here methods can directly invoked by the class itself.
They are already defined in the JVM. We don't need to instantiate to use methods of this class.
So, I'm beginning to learn Java and I think it's an awesome programming language, however I've come across the static keyword which, to my understanding, makes sure a given method or member variable is accessible through the class (e.g. MyClass.main()) rather than solely through the object (MyObject.main()). My question is, is it possible to make certain methods only accessible through the class and not through the object, so that MyClass.main() would work, however MyObject.main() would not? Whilst I'm not trying to achieve anything with this, I'd just like to know out of curiosity.
In my research I couldn't find this question being asked anywhere else, but if it is elsewhere I'd love to be pointed to it!
Forgive me if it's simple, however I've been thinking on this for a while and getting nowhere.
Thanks!
Any static method or member belongs to the class, whereas non-static members belong to the object.
Calling a static method (or using a static member) by doing myObject.method() is actually exactly the same as MyClass.method() and any proper IDE will give a suggestion to change it to the second one, since that one is actually what you are doing regardless of which of the two you use.
Now to answer the actual question:
is it possible to make certain methods only accessible through the class and not through the object
No, not as far as i know, but like I said, any proper IDE will give a warning, since it makes little sense and it gives other readers of the code an instant hint that you're dealing with static members.
Yes, short answer is no.
But you can put your static members in a dedicated class, so that no instances share any one of them.
MyObject is instance of MyClass, and you aggregate all you static parts in MyStaticThing.
Using static member on an instance can be misleading, so it is a bad practice
http://grepcode.com/file/repo1.maven.org/maven2/org.sonarsource.java/java-checks/3.4/org/sonar/l10n/java/rules/squid/S2209.html
While it is possible to access static members
from a class instance, it's bad form, and considered by most to be
misleading because it implies to the readers of your code thatthere's
an instance of the member per class instance.
Another thing, do not use static things, because you cannot do abstraction and replace implementations to extend your code.
Being able to switch between implementations is useful for maintenance and tests.
In Java, you can crete an object with these keywords.(new keyword, newInstance() method, clone() method, factory method and deserialization) And when you create an object,it can also use classes abilities which is like static methods.
Short answer:No.
Is it possible to make certain methods only accessible through the class and not through the object?
Yes, it is. You achieve this by preventing any instances of the class to ever be created, by making the class non-instantiable: declare its constructor private.
public final class NonInstantiable {
private NonInstantiable() {
throw new RuntimeException(
"This class shouldn't be instantiated -- not even through reflection!");
}
/* static methods here... */
}
Now, it only makes sense to declare any methods of the class static -- and they can only be called through the class name. Such a class is often called a utility class.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is a class literal in Java?
I was going through literals in the Java tutorial where I came across this sentence:
Finally, there's also a special kind of literal called a class literal, formed by taking a type name and appending ".class"; for example, String.class. This refers to the object (of type Class) that represents the type itself.
Which doesn't make any sense to me, even though I paid attention to all the other topics prior to this. Can anyone explain in simple language with examples or references?
Instances of the class java.lang.Class represent classes and interfaces in a running Java application. For each class in the application, there is an instance of Class. The SomeClass.class syntax is a way to get from SomeClass to the corresponding instance of Class.
A class literal is just a special type to use when you want to do something involving the class itself, rather than an instance.
Here's a short list of a few things I commonly use this for (not at all comprehensive, but you can get a good idea)
1.) Reflection, you want to instantiate something in run-time that you may not know (perhaps it was stored in a variable of type Class)
2.) You want to check if 2 objects are of the same related type, you can write something along the lines of: B.class.isAssignableFrom(a.getClass());
3.) You want to list all the methods, or public variables within a class, perhaps for documentation.
There are many other uses, but these are the main ones I find myself using in common practice.
Speaking simple language: that thing, which you call class literal is an object which fully describes some class: all its methods, all its fields, all its annotations, class's modifiers and so on. It is needed for creating new instances of that class in runtime.
Short example:
Class x = String.class;
System.out.println(x);
you can use x to create runtime instances of the class it points to or to test the class of an object against it.
It evaluates to be the class identifier of the reference or primitive type's wrapper class. The expression void.class evaluates to the class identifier of the Void class. Same thing with 'String.class'
I am storing a list of classes through (Classname.class) and would like to instantiate one? Is this possible?
newInstance seems to the method I am after but it doesn't support a constructor?
You can use Class.getConstructors (or Class.getConstructor) to get a list of available constructors, and invoke any of them with Constructor.newInstance, which does accept parameters.
Just to add one point I see missing:
You can invoke newInstance directly on the Class object if it has a public null constructor. (Null constructor is the constructor with no arguments.)
Otherwise, you can find constructors via Class.getConstructors() as others have said.
The Java tutorial on reflection covers this well. But yeah, basically Class.getConstructors, then Constructor.newInstance is where it's at.
Java is designed so you can never "trick" it as long as you use the java.lang/java. classes or other standard libraries. One of the most important things of OOP is that objects should be in a defined state, thus you can be safe that the constructor is always run. Even if you're using some strange-looking reflection libraries to get your work done.
So, using Class.forName("me.Test").newInstance(); (or similar) will under-the-hood invoke the Test() constructor for you.
If you want to invoke another constructor the code is something like:
Test test = (Test)Class.forName("Test").getConstructor(String.class).newInstance("Hello World");
Here the getConstructor asks what the constructor looks like (it wants a string) and then you call it with a string.
You cannot construct new classes this way.
If you have the name of a class you can use Class.forName(className) to load/reference a class.
If you have the byte code for a class you want to create you can have a class loader load the byte code and give you the class. This is likely to be more advanced than you intended.
If you have a list of Class objects obtained through class literals, you might as well statically reference the constructors rather than slipping into reflection evilness.