I am curious about keywords in Java.
Should I understand it as a class of various methods that get created with every instance of user-defined classes, like the ultimate “super” class? How is it defined in the Java?
So for example, I came across this:
class A {
class B {}
}
A a = new A();
B b = a.new B();
This seems like each class has keyword new as its own method. I would appreciate any insights on how keywords are defined/implemented in Java.
Classes don't have keyword "new" as a personal method or anything like that. It is the Java language itself that has the keyword "new". So in other words you put "new" in the code the compiler would recognize it and instantiate a new Object.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.9- this link is the documentation of Java language, in section 3.9 it shows all the keywords.
Edit:
Like others are saying, what the snippet of code in your question indicates an inner class, so for instance, like it says in http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
The following is the output of this example:
x = 23
this.x = 1
ShadowTest.this.x = 0
This shows that the innerclass or class B(FirstLevel) is like or similar to the outer class's variables and methods(for it is associated with the instance of the outer class) of class A(ShadowTest).
As all the languages ,Java has Keywords. Here the new keyword is used for initialization purposes.here the object of the class A is initialised in the first statement. in second statement the object of class B is initialised with class A's object A
Keywords in the simplest words are the predefined words which have some predefined specific meaning and cannot be used for any other purpose.
Check full list of keywords in Java
Now to elaborate this thing I would take example of two keywords, int and float. An int keyword is used to define an integer variable and that is all what a keyword int can do. We cannot use it for any other purpose. Similarly, float keyword can be used to define a float/decimal number variable, nothing else.
int a = 10;
I defined a variable a of integer type.
int float = 20; <----- It won't work.
In this example, I am trying to declare an integer type variable with name float, which is not possible, as float it self is a keyword, so it cannot be used as an identifier.
If we talk about new keyword, then it is used to create objects of any class or I would more precisely say, new keyword allocates memory to the objects at run time.
It is NOT like that every class has its own new keyword. new is Java's keyword so any Java class can use it.
To clarify,
A a = new A();
B b = a.new B();
In the first statement, we are creating an object of class A and as class B is the nested class of class A, so we cannot access it directly. So to access it, we are using the object of class A, which we already have built.
Related
class A {
public int a = 100;
}
class B extends A {
public int a = 80;
}
class C extends B {
public int a = 10;
public void show() {
int a = 0;
System.out.println(a);
System.out.println(super.a);
System.out.println(((A) this).a);
}
}
What does ((A) this).a in the line System.out.println(((A) this).a); do?
Is it upcasting/downcasting thisor is something else happening here?
I also tried System.out.println(this); and System.out.println((A)this); and they both have the same output. What exactly is happening here?
In the java programming language, we have classes. When we write java code, we create instances of those classes, for example:
Object o = new Object();
Object is a class. Writing new Object() creates an instance of that class. The above code declares a variable o and assigns it [a reference to] an instance of class Object.
In the terminology of the java programming language, we say that variable o has type Object.
In the code in your question, a variable that is assigned an instance of class C, really has three types.
It has type C.
It has type B since B is the superclass of C.
It has type A because it indirectly extends class A also.
In the context of the code in your question, this is a special variable whose type is C. Writing (A) this is telling java to relate to the variable this as if its type is A.
Class A cannot access its subclasses. Hence it is only aware of its class member a. Hence when you write this line of code...
((A) this).a
You are accessing the member of class A only.
System.out.println(a);a is the one from the show method of your C class → a = 0
System.out.println(super.a);a is the one from the super-class of C, which is B → a = 80
System.out.println(((A) this).a);First, you cast your C instance (this) into A, then you call a which is a member of the A class → a = 100
There is also something to consider : method will always take the more specialized one (except if super is used), where field will be taken directly from the type referenced (even if there is an extending class).
For example, if I add getA() in each classes :
class A {
public int a = 100;
public int getA(){
return a;
}
}
class B extends A {
public int a = 80;
public int getA(){
return a;
}
}
class C extends B {
public int a = 10;
public int getA(){
return a;
}
public void show() {
int a = 0;
System.out.println(a);
System.out.println(super.a);
System.out.println(((A) this).a);
System.out.println(getA());
System.out.println(super.getA());
System.out.println(((A) this).getA());
}
}
class Scratch {
public static void main(String[] args) {
new C().show();
}
}
I get the following output :
0
80
100
10
80
10
Which means that in the case of the method, except in the case of super.getA() which explicitly goes to the superclass, casting your C into a A doesn't change much for methods, as it impacts the field.
If you write something like obj.a, obj.getA() or someMethod(obj), Java somehow has to find the actual field or method to be used, based on the type or class of obj. There are two distinct dispatch mechanisms involved (plus the special construct super).
Dynamic dispatch (polymorphism, overriding): This is used when calling an instance method on the object, as in obj.getA(). Then the runtime class of the obj is examined, and if this class contains a getA() method, this is used. Otherwise, the direct parent class is examined for a getA() method, and so on up to the Object class.
Static dispatch: In cases like obj.a or someMethod(obj), the runtime class of obj doesn't matter. Involved is only the compiler, and from his knowledge of obj's type, he decides which field or method to use.
super dispatch: If you write super.getA() or super.a, your getA() method or a field is ignored, and instead the next-higher class in the hierarchy is used that contains such a method or field.
In your case you have 3 fields plus one local variable, all with the same name a. (By the way, it's a very bad idea to have such name conflicts in professional code.) We are inside a method show() declared in the C class. Let's have a look at some different expressions and what they mean here:
a references the local variable a. There's no dispatch needed, it's just that local definitions take precedence over fields.
this.a is a static-dispatch expression, so it's important what the compiler thinks about the type of this. And that's always the class where this code has been written. In your case, it's class C, so the field a from class C is used, the one being 10.
super.a is a super-dispatch expression, meaning that the a field from this class C is ignored and the next higher one taken (the one from B, in our case).
((A) this).a is static dispatch, but the (A) casting has a significant effect. The expression before the dot originally comes from this, being of type C, but the (A) cast tells the compiler to believe it were of type A. This is okay, as every C also is an A, by inheritance. But now, static dispatch sees something of type A in front of the dot, and dispatches to the a field from the A class, and no longer from C.
getA(), this.getA() and ((A) this).getA() are all dynamic-dispatch examples, all giving the same result. The method called will be the one based on the runtime class of this object. This will typically be one defined in the C class. But if show() was called on an object of a subclass of C, e.g. D, and D had its own getA() method, that one would be used.
super.getA() is a case of super-dispatch, it will call the getA() method next higher up in the class hierarchy from the current class, e.g. B.
System.out.println(this);
And
System.out.println((A)this)
These two prints the object reference to class C with toString() method.
System.out.println(((A)this).a);
This is upcasting, child object to parent object.
I'm studying computer engineering, my 2nd semester just began. I've been making Android applications for a few while.
My programming lecturer (teaches C++ (Object Oriented)) said we can't initialize variables in a class unless we use a constructor since there's no memory dedicated to those data members before making an object of that class.
He said this is incorrect:
class example
{
int a = 0;
};
But my experience says something else:
I've made a class in my Android project that keeps my Constants. I don't make any objects of that class. I've initialized variables and never used a constructor. But it works fine:
public class Constants {
public static final int a = 1;
}
I want to know how am I initializing variables when there's no memory dedicated to that variable and how it works.
What part of my story is wrong? I want to know how my code works when there's no memory dedicated to my variables (Constants)?
The Truth
class A {
int a = 0;
};
In-class initializers became legal in C++11; so the only conclusion to draw from what you have said is that your teacher is living in the past.
However, if he is teaching C++03 and not a later revision of the language, he's correct about it being ill-formed.
It is important to note that what he said regarding (non-static) data-members and their lack of storage until an object of such class has actually been created still applies.
An in-class initializer will initialize the data-member during construction, as long as the data-member isn't initialized in the used constructor's mem-initializer (then the latter takes precedence).
struct A {
A () = default;
A (int x) : m (x) { }
int m = 0; // ^ mem-initializer
};
A x; // `x.m` is initialized to `0`
A y (123); // `y.m` is initialized to `123`
Further Reading
cppreference.com - Non-static data members : Member Initialization
He said this is incorrect:
class example
{
int a = 0;
}
Well, yes, it's incorrect, there needs to be a semicolon at the end, after the }.
With that semicolon, this is legal C++11; the = 0 is a non-static data member initializer (NSDMI for short). It's syntatic sugar for performing the equivalent initialization in the constructor.
public class Constants {
public static final int a = 1;
}
static things are per-class, and exists even if no objects of that class is ever created. Non-static things are per-object.
This question already has answers here:
What causes error "No enclosing instance of type Foo is accessible" and how do I fix it?
(11 answers)
Closed 6 years ago.
I am trying to initialise the array C in the loop, but it gives error :
C is array of class ipdata and I have declared it and trying to initialise it inside the loop.
import java.io.*;
import java.util.*;
public class cluster_anlysis {
class ipdata{
float a,b;
int cluster;
ipdata()
{
a=0;
}
}
public float modc(float a){
if(a<0.0)
a=-a;
return a;
}
public static void main(String[] args) {
cluster_anlysis obj=new cluster_anlysis();
ipdata C[] = new ipdata[50];
float mean1,mean2,mean3;
int i,j,n1=0,n2=0,n3=0,flag=0;
float ina=0.0f;
float inb=0.0f;
//BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
Scanner scan =new Scanner(System.in);
System.out.println("pls enter no of data: ");
Integer no = scan.nextInt();
System.out.println("\nnow enter the x and y values");
for(i=0;i<no;i++)
{
ina=scan.nextFloat();
inb=scan.nextFloat();
System.out.println(ina);
C[i]= new ipdata(); // this line is giving error
C[i].a=ina;
C[i].b=inb;
C[i].cluster=0;
}
}
}
What could be the problem ?
it says :
No enclosing instance of type cluster_anlysis is accessible. Must qualify the allocation with an enclosing instance of type cluster_anlysis (e.g. x.new A() where x is an instance of cluster_anlysis).
you create an instance of inner class from static methods of your outer class using the outer class instance.
c[i]= new cluster_anlysis().new ipdata();
as you have alread created cluster_anlysis instance in your first line of main method.
cluster_anlysis obj = new Cluster_anlysis();
you could simple do.
c[i]= obj.new ipdata();
read about Inner classes in java
but if you want to create an inner class instance from the non-static methods of your outer class you dont need the instance of your Outer Class .
public class OuterClass {
public void method(){
InnerClass inner = new InnerClass();
}
class InnerClass{
}
}
and also follow class name convention as posted by #A.R.S and #JB Nizet in their solutions.
It seems you're starting with Java. I would advise to avoid messing with inner classes for the moment. Define each Java class in its own file, and everything will be simpler.
Also learn about Java naming conventions:
classes start with an upper-case letter, and are CamelCased: ClusterAnalysis, IpData. They should not contain underscores.
variables start with a lower-case letter, and are camelCased: c. They should not contain underscores.
Once you are more comfortable with the basics, learn about inner classes and static inner classes in the Java tutorial. But inner classes should not be abused. The basic rule is to have one class per file.
Use outer class Instance to call inner class constructor
like
c[i]=new cluster_analysis().new ipdata();
I think the best thing to do would be to declare ipdata as static; that would eliminate the error. There should be no need to instantiate cluster_analysis in order to instantiate ipdata in this case, and it makes sense that ipdata should in fact be static.
Oh, and by convention, you might want to consider using the names IpData and ClusterAnalysis instead - class names generally start with a capital letter and are "CamelCased", as another answer also pointed out.
public class A{
}
A a = new A(){{
final int x = 1; // IT HAS TO BE FINAL HERE. WHY?
}};
A aa = new A(){
int x = 1; // THIS NEED NOT BE FINAL. WHY?
final int y = 1; // STILL FINAL IS ALLOWED HERE. WHY?
public int getX(){
return x;
}
};
Can somebody please answer the questions mentioned inside the snippet?
Thanks
The outer set of {} declares an anonymous subclass
The inner set declares an initialization block within that subclass.
With the following example, it becomes easier to understand what's going on:
List<String> strings = new ArrayList<String>() {{
add("string");
add("another string");
}};
You basically say: I want a subclass of List, which calls method add at initialization.
It's similar to:
List<String> strings = new ArrayList<String>();
strings.add("string");
strings.add("another string");
A a = new A(){{
final int x = 1; // IT HAS TO BE FINAL HERE. WHY?
It needn't.
The difference between the two is that in the first case, you're writing the code used to initialize each object in the double braces. That x is its local variable (doesn't have anything to do with objects of class A).
In the second case, you're defining the classes body. x would be its member variable. If it were static, its class variable. If final a (basically) constant.
I wonder, why would you want to use the first version of the code (the one with {{}}). The x variable declared inside it's not useful at all, it's local only to the block scope in which it was defined, and being inside an anonymous class, you won't be able to reference it anywhere in the code.
And anyway, the first version of x declaration does not need to be final, it compiles just as fine, with or without final.
In your first example the inner braces create something called an instance initializer. It's an obscure way to initialize variables and call instance methods when an object is constructed. So the first example creates an anonymous subclass of A and creates a local variable within the scope of the initializer. It doesn't have to be final.
In the second example you're creating an anonymous subclass of A but not creating an instance initializer, the variables you create are instance variables of the anonymous subclass.
The first instance A a = new A(){{... has an initialisation block inside the declaration. Another way of writing it would be like this:
A a = new A()
{
{
final int x = 1; // This is inside an initialisation block
}
};
Changing the formatting makes it a bit more obvious.
By convention, a static method specifically in Java can have access only to static fields or other static methods. The following simple code snippet however appears to violate the convention. Let's consider the following simple code snippet in Java.
class Super
{
protected static int x;
protected static int y;
public Super(int x, int y)
{
Super.x=x;
Super.y=y;
}
public static int sum()
{
return(x+y);
}
}
final class Sub extends Super
{
public static int temp=100;
public Sub(int x, int y)
{
super(x, y);
}
public void concreateMethod()
{
System.out.println("\nInstance variable x = "+x);
System.out.println("Instance variable y = "+y);
}
}
final public class Main
{
public static void main(String[] args)
{
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
System.out.println("\nConcreate method called.");
s.concreateMethod();
}
}
The above code produces the following output with the respective statements.
Associating with object x = 10
Associating with object y = 5
Associating with class name x = 10
Associating with class name y = 5
Summation (Associating with object) = 15
Summation (Associating with class name) = 15
Associating with class name temp = 100
Associating with object temp = = 100
Concreate method called.
Instance variable x = 10
Instance variable y = 5
The static fields s and x are being accessed through the following statements within the main() method using the object of the Sub class, though they are declared as static in the super class Super.
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
The following statements of course, have no doubt.
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
Since x and y are static, they can certainly be accessed in this way.
The same is the method call, observe the following statements.
Sub s=new Sub(10, 5);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
Both of the ways, the static method sum() is being accessed using the object of the class Super and also using the class name Sub.
Again the similar case with the static field temp declared within the Sub class
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
The static field temp is being accessed in both the ways.
Why is this happening here?
Basically it's a flaw in the design of Java IMO which allows static members (methods and fields) to be referenced as if they were instance members. This can be very confusing in code like this:
Thread newThread = new Thread(runnable);
newThread.start();
newThread.sleep(1000);
That looks like it's sending the new thread to sleep, but it actually compiles down into code like this:
Thread newThread = new Thread(runnable);
newThread.start();
Thread.sleep(1000);
because sleep is a static method which only ever makes the current thread sleep.
Indeed, the variable isn't even checked for non-nullity (any more; it used to be, I believe):
Thread t = null;
t.sleep(1000);
Some IDEs can be configured to issue a warning or error for code like this - you shouldn't do it, as it hurts readability. (This is one of the flaws which was corrected by C#...)
There is no problem there. Static methods can only access static fields and call other static methods as you have stated. Nothing in your examples does otherwise.
Non-static methods can access both static and non-static methods and fields. Again, none of your examples violate that.
The Sub.temp and s.temp are equivalent and you can use both, it means the same. But 1st is better one because suggests it's a static field.
a static method specifically in Java can have access only to static fields or other static methods declared within the same class
Or its superclass.
I don't see any violation here, you can access static fields/methods via its concrete object or class name. both refer to the same thing.
Where do you see a non-static field or method being accessed by static code? Everything seems perfectly fine to me.
Perhaps what's confusing you is that static fields and methods can be accessed through instances as well as through the class name? It's certainly a big ugly and many consider it bad design, but that's all.