This question already has answers here:
Does an inner class work as a composition relationship in java? [closed]
(3 answers)
Closed 5 years ago.
I'm trying to delevope intuition and familiarity with inner classes.
I'm apporaching myslef to this java's topic and after some research I've started practicing.
I came up with this piece of code that behaves in a way that I can't understand.
I created a class Example with a public inner class Inner.
Inside the Example class I created an object of the Inner class obj, and in the class MainClass, inside the main function I created another Inner class instance ( After creating the instance of the enclosing class).
Example class code:
public class Example {
Inner obj = new Inner(9);
class Inner {
public int x;
public Inner(int a) {
x=a;
}
}
}
Main class:
public class MainClass{
public static void main ( String args[] ) {
Example example = new Example();
System.out.println(example.obj.x); // output 9
Example.Inner obj = example.new Inner(10);
System.out.println(obj.x); //output 10
System.out.println(example.obj.x); // output 9
}
}
Given that the statements Inner obj= new Inner() and the statement Example.Inner obj = example.new Inner(10) both declare an object of the Inner class with the same name, I don't understand how this not give any problem.
I think it's reltaed ot how they are loded in memory, but they seem to be 2 completley different things but I don't understand how.
UPDATE:
Answers have been great till now, I edited the question changing the code and reducing the number of constructors to one. This should clarify what my doubts concern.
You have two instances of Inner class, although both instances have same name obj, they are separate from each other. Inner class instance defined outside main method is created using default constructor. So example.obj.x outputs 6.
Inner class instance obj defined inside main method is created using parameterized constructor so obj.x outputs 10.
Important thing here is that when you do example.obj.x, you are referring to the instance of Inner class created outside main method and when you do obj.x, you are referring to the Inner class instance created inside main method. These two instances of Inner are completely separate from each other.
EDIT
Answers have been great till now, I edited the question changing the
code and reducing the number of constructors to one. This should
clarify what my doubts concern.
Having one or two constructors won't change anything. Inner class instance defined outside main method and the one defined inside main method are two separate instances of Inner class.
x, data member of instance of Inner defined outside main has value of 9 and can only be accessed using Example class's instance example. Hence example.obj.x outputs 9.
Instance of Inner defined inside main is directly accessible using obj defined inside main and its x has a value of 10. Hence obj.x outputs 10.
You've created two objects: example, an instance of Example, and obj, an instance of Example.Inner. These two objects have nothing to do with each other, and share no information, so the x field in each can hold a different int.
Irrespective of the fact that you have an inner class, you have two completely different instances of Inner.
example.obj.x is assigned the value of 6 due to the constructor for Inner assigning 6 to x.
obj is instantiating a new instance (hence the keyword new), and then it's passing in the value 10 for its constructor.
This is why you get two different values; because these two instances are completely separate from one another and have no shared values between each other (i.e. static field), the values will be different.
Related
This question already has an answer here:
What happens in the heap when class A inherits class B in Java
(1 answer)
Closed 3 years ago.
Consider a Superclass A and a derived class B whereas A contains a private variable x. B contains an explicit super() call as first argument inside its constructor while there might be some other variables of B like y and z. As far as I know there is no inheritance for private fields. Does that mean private fields will not get instantiated while executing:
B b = new b();
My question is: How does the heap look like after running the above code? Of course there will be y and z, but what about x in this case?
Field inheritance and field visibility are two separate concepts, not to be confused.
Field inheritance
In a way (to simplify a bit), a class is a template from making objects. So if a class A declares two fields f1 and f2, then instantiating A creates objects (and allocates memory for them on the heap) that have these two fields.
A subclass is also a template for making objects, but this template is expressed as an addition to another class. So if class B declares field f3 and extends A, it's basically saying, "take all the fields that A defines, and add f3". So instantiating B results in an object with three fields f1, f2, f3.
Field Visibility
Field visibility, as expressed through access modifiers like private and public, is a way to control which part of the code "sees" (or can refer to) a certain field. The private modifier means that no code outside of the class that declares the field can refer to this field. However, it doesn't mean that the field stops existing. To make a dodgy parallel, if you and another person are in a room and you turn off the light, you can't see the other person, but they are still there.
To emphasize the point that the concepts are separate, consider that in some cases you can see fields that are not inherited (e.g., because they are non-private, but in a class not in the same class hierarchy). And in some cases you can't see fields that are inherited, as in the case of private fields in the superclass.
The private field defined in the super class is instantiated when a statement does that.
The fact that you manipulate a subclass doesn't change anything on this point. The field is always existing and instantiable, just the subclass cannot access it directly.
If the field of the super class was not instantiable, the Java inheritance would make not any sense since the subclasses would be not consistent or even unusable as superclass methods will not work any longer.
For example :
private int x;
A(){
this.x = getIntValue();
}
int getX(){return x;}
And B the subclass :
B(int x){
super(); // in the compiled code even if not in the source code
}
new B().getX() will of course return the value of x instantiated in the superclass.
This question already has answers here:
Difference between Static methods and Instance methods
(10 answers)
Closed 4 years ago.
Whenever I have to call a method from another class, I first create an object and then call it through the object. But while I was writing some code, I mistakenly wrote classname.methodname(); and it worked.
I would usually write,
classname obj = new classname();
obj.methodname();
Here is the actual code:
Class 1
public class Dataset {
public static List<ECCardData> getDataset() {
//Code
}
in Class 2
List<ECCardData> dataset = Dataset.getDataset();
I noticed that the methodname() was static. Was that the reason?
Yes, for static methods (with suitable access modifier) you can call directly with your class by
YourClass.yourMethod();
and this way, too
YourClass anObject = new YourClass();
anObject.yourMethod();
Happy coding.
I hate answering my question, but I found the correct answer.
When a method is declare static, only one instance of that method will exist. When you create an object a new instance of the method is created, which is not possible for a static method. Therefore you use the class name.
classname.methodname(); //only one instance
classname obj;
obj.methodname(); //instance with obj as Object(IDE gives warning, should not be allowed, ideally)
The basic paradigm in Java is that you write classes, and that those
classes are instantiated. Instantiated objects (an instance of a
class) have attributes associated with them (member variables) that
affect their behavior; when the instance has its method executed it
will refer to these variables.
However, all objects of a particular type might have behavior that is
not dependent at all on member variables; these methods are best made
static. By being static, no instance of the class is required to run
the method.
You can do this to execute a static method:
classname.staticMethod();//Simply refers to the class's static code But
> to execute a non-static method, you must do this:
>
> classname obj = new classname();//Create an instance
> obj.nonstaticMethod();//Refer to the instance's class's code
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
Would you:
add types above the main method and then initialize them under the method
public class Main {
private Person person;
public void method() {
person = new Person("Bob", 30);
add types above the main method AND initialize them
public class Main {
private Person person = new Person("Bob", 30);
public static void main(String[] args) {
add types under the main method AND initialize them
public class Main {
public static void main(String[] args) {
Person person = new Person("Bob", 30);
I would like to know when you would use which way and why.
I appreciate any input!
a) The private modifier is not allowed inside a method, so your third example will not even compile.
b) Only your 2nd example actually compiles. The first one has a non-static member of class "Main" and you try to set it directly inside a static method.
c) The examples are not equal. The third one has a local variable in the method (assuming we ignore the private modifier), the other two have a member variable of "Main".
a&b vs. c depends on where you need your variable. If you only need it inside the method, declare it there.
a vs. b depends primarily on what readability and use cases. If you CAN initialize your variable there and if it doesn't lead to unreadable code, do it. Otherwise, do it in the constructor or any init method.
Personally, I tend to mostly declare final objects directly, non-final objects can be initialized elsewhere (because declaring them directly makes it look pretty final even if they aren't).
This is not a question of common practice, because the three examples you gave actually have different meanings. So it's more a matter of understanding variable declarations.
A variable declaration is declaring the name, type and optionally, the initial content of a variable you need to use.
String s = "abc";
↑ ↑ ↑
type name initializer
Now take a look at a class definition:
class A {
// Class body scope
}
Everything declared inside a type body (class, interface, enum) is a member of that type. Members include fields, methods and nested classes. Variable declarations in this scope (outside of any method) are fields, and they can be instance fields and static fields. If they have the modifier static, they are shared by all the members of the class and in fact can be used without having an actual instance of this class. If they don't have that modifier, then they are instance fields.
Instance fields can't be used without having an actual instance. So they are not available to static methods like main, only to instance methods. Thus, your first example won't work - main is trying to put a value in an instance field (as it doesn't have the word static).
In the second example, you're still creating an instance field, but this time you are giving it an initial value. This is fine - but you still won't be able to access this information from main. This is merely a field that will exist separately in every new Main object you will create (if you create one).
In the third example, you are creating the variable inside a method. In this case, the variable is not a field. It is a local variable. As such, it cannot have access modifiers such as private and public, because local variables are only accessible inside the method where they are declared (in fact, inside the block where they are declared).
But if you remove the access modifier, this will work, and you'll be able to use it in main, but not outside of main.
Generally, the question whether to give the variable an initializer or assign to it later on depends on whether it's a field or a local variable, whether it is final or not, static or not, and whether you have a meaningful value for it when you create it. For local variables, it's recommended:
To declare it as close as possible to where it is going to be used.
To give it a value as soon as a meaningful value can be given.
In practice this means that most of the time you'll have an initializer in local variable declarations, if only to avoid pesky "variable may not have been initialized" compiler warnings.
For fields, especially if they are declared final, you're going to need to initialize them as soon as possible, but not necessarily with an initializer. You might do so in a constructor (for an instance field), or in an initializing block (for a static field whose value needs to be determined by a complex operation).
If the only place you need tha variable 'person' is your Main method, you should declare and initialize 'person' as you did in the third example.
If you need that somewhere else, I would say you can do whatever you want to, but don't switch between those to make your code readable.
I have come across below strange syntax, I have never seen such snippet, it is not necessity but curious to understand it
new Object() {
void hi(String in) {
System.out.println(in);
}
}.hi("strange");
Above code gives output as strange
thanks
You've created an anonymous sub-class of Object, which introduces a method, called hi, after which you invoke this method with parameter "strange".
Let's suppose you had:
class NamedClass extends Object {
void hi(String in) { System.out.println(in); }
}
NamedClass instance = new NamedClass();
instance.hi("strange");
If this class was needed at exactly one place, there's no real need of being named and so on - by making it an anonymous class, you get rid of its name, the class gets defined and instantiated and the hi method invoked immediately within a single expression.
You've created an annonymous sub-class of Object and then invoke the method.
Four types of anonymous inner class exists :-
1)Inner class,
2)Static nested classes
3)Method local inner classes
4)Anonymous inner classes
In Annonymous inner classes,you can define,instantiate and use that inner object then and there
This is perfectly normal and is Called an anonymous class it is used very often where if u want to pass an object reference to a function you will do it with anonymous classes or for the use of callbacks, now .hi at the end is valid because you just used the new operator to instantiate an object of type Object and you have a reference to it so that's why it works.
I'm beginning to program in Java.
public static void main(String[]args)
A book said that I should use static in this case, but doesn't clearly say why I should or what it means.
Could you clarify this?
The concept of static has to do with whether something is part of a class or an object (instance).
In the case of the main method which is declared as static, it says that the main method is an class method -- a method that is part of a class, not part of an object. This means that another class could call a class method of another class, by referring to the ClassName.method. For example, invoking the run method of MyClass would be accomplished by:
MyClass.main(new String[]{"parameter1", "parameter2"});
On the other hand, a method or field without the static modifier means that it is part of an object (or also called "instance") and not a part of a class. It is referred to by the name of the specific object to which the method or field belongs to, rather than the class name:
MyClass c1 = new MyClass();
c1.getInfo() // "getInfo" is an instance method of the object "c1"
As each instance could have different values, the values of a method or field with the same name in different objects don't necessarily have to be the same:
MyClass c1 = getAnotherInstance();
MyClass c2 = getAnotherInstance();
c1.value // The field "value" for "c1" contains 10.
c2.value // The field "value" for "c2" contains 12.
// Because "c1" and "c2" are different instances, and
// "value" is an instance field, they can contain different
// values.
Combining the two concepts of instance and class variables. Let's say we declare a new class which contains both instance and class variables and methods:
class AnotherClass {
private int instanceVariable;
private static int classVariable = 42;
public int getInstanceVariable() {
return instanceVariable;
}
public static int getClassVariable() {
return classVariable;
}
public AnotherClass(int i) {
instanceVariable = i;
}
}
The above class has an instance variable instanceVariable, and a class variable classVariable which is declared with a static modifier. Similarly, there is a instance and class method to retrieve the values.
The constructor for the instance takes a value to assign to the instance variable as the argument. The class variable is initialized to be 42 and never changed.
Let's actually use the above class and see what happens:
AnotherClass ac1 = new AnotherClass(10);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
Notice the different ways the class and instance methods are called. The way they refer to the class by the name AnotherClass, or the instance by the name ac1. Let's go further and see the behavioral differences of the methods:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
AnotherClass.getClassVariable(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
AnotherClass.getClassVariable(); // Returns "42"
As can be seen, an instance variable is one that is held by an object (or "instance"), therefore unique to that particular instance, which in this example is the objects referred to by ac1 and ac2.
A class variable on the other hand is only unique to that entire class. To get this point across even better, let's add a new method to the AnotherClass:
public int getClassVariableFromInstance() {
return classVariable;
}
Then, run the following:
AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);
ac1.getInstanceVariable(); // Returns "10"
ac1.getClassVariableFromInstance(); // Returns "42"
ac2.getInstanceVariable(); // Returns "20"
ac2.getClassVariableFromInstance(); // Returns "42"
Although getClassVariableFromInstance is an instance method, as can be seen by being invoked by referring to the instances ac1 and ac2, they both return the same value, 42. This is because in both instance methods, they refer to the class method classVariable which is unique to the class, not to the instance -- there is only a single copy of classVariable for the class AnotherClass.
I hope that some what clarifies what the static modifier is used for.
The Java Tutorials from Sun has a section called Understanding Instance and Class Members, which also goes into the two types of variables and methods.
Please see a nice description on Wikipedia
For example, notice how in the Math class, you can say things like
Math.Abs(x);
without having to say
Math m = new Math();
These are static methods since you don't need an instance. Instance methods are those methods that require you to have an instance of a class.
Employee e = new Employee();
e.Terminate();
A static method is one that applies to the class a whole, not any particular member. .goExtinct() would be a method of the Duck population as a whole, not any particular duck. main is public and static because is has to always be available, and its not part of any particular class.
Usually, you have to have an object, an instance of a class, in order to call methods on it, for at least two reasons:
It depends on the object which class implements the method that is being called. For example if you have an instance of a subclass, the method in the subclass will be called instead, even though the code that calls the method is the same.
Objects usually have internal state (fields), that methods can refer to. This does not work if there is no object instance.
You create object instances by calling the class' constructor:
MyObject a = new MyObject();
Static methods are methods that are not attached to object instances. They can be called by just naming the class. As a result of this they
cannot be dynamically dispatched to subclasses (which is why you get a warning when you try to call it on object instances, that is just confusing syntax)
they cannot refer to instance state (non-static fields and other non-static methods).
Many people consider static methods a bad design pattern, and advise to not use them (except for public static void main) Look up the singleton instance pattern for an alternative.
In this particular case the main method must be static, because of the way the JVM will start loading classes and creating objects. When you start a Java program the JVM will look for the definition of the class that was passed to it and load it. So java MyClass will result in loading the definition of the MyClass class.
By definition a Java program will start executing in the main() method of the class that was passed to the JVM as the class to load initially. At this point in time no instance (object) of type MyClass has been created, so the main method has to be static to allow the start of the execution of your program.
If you want to see which classes are being loaded during the execution of a Java program you can use the -verbose:class command line option.
In any object oriented programming language like Java or C++ you create classes which at the very basic level are like BluePrints of a building. You can look at a blueprint and determine how various components are connected but you cannot actually live in it. It's the same with classes and object. Classes are blueprint and you create an instance of a class which is called an Object. For the same blueprint you can have multiple buildings , same way for one class you can have multiple objects. An Object is an instance of a class. Each method in a class can be called on an Object or an instance of a class, whereas for calling static methods you actually don't need an instance, you can directly call ClassName.method() without actually creating an instance of a class.
There will be times when you will want to define a class member that will be used independently of any object of that class. Normally a class member must be accessed only in conjunction with an object of its class. However, it is possible to create a member that can be used by itself, without reference to a specific instance. To create such a member, precede its declaration with the keyword static. When a member is declared static, it can be accessed before any objects of its class are created, and without reference to any object. You can declare both methods and variables to be static. The most common example of a static member is main( ). main( ) is declared as static
because it must be called before any objects exist.
The two types of static members are static fields and static methods:
Static field:
A field that’s declared with the static keyword, like this:
private static int ballCount:
The position of the static keyword is interchangeable with the positions of the visibility keywords (private and public, as well as protected). As a result, the following statement works, too:
static private int ballCount;
As a convention, most programmers tend to put the visibility keyword first.
The value of a static field is the same across all instances of the class. In other words, if a class has a static field named CompanyName, all objects created from the class will have the same value for CompanyName.
Static fields are created and initialized when the class is first loaded. That happens when a static member of the class is referred to or when an instance of the class is created, whichever comes first.
Static method:
A method declared with the static keyword. Like static fields, static methods are associated with the class itself, not with any particular object created from the class. As a result, you don’t have to create an object from a class before you can use static methods defined by the class.
The best-known static method is main, which is called by the Java runtime to start an application. The main method must be static, which means that applications run in a static context by default.
One of the basic rules of working with static methods is that you can’t access a nonstatic method or field from a static method because the static method doesn’t have an instance of the class to use to reference instance methods or fields.