This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can a class have a member of its own type, isnt this infinite recursion?
The Code:
public class Test2{
private Test2 subject = new Test2(); //Create Test2 object in Test2
private int num;
}
The Questions:
Why does Java permit the above code to be executed, but C++ doesn't?
Does the code above create infinite number of objects? Since Test2 itself contains a Test2 object which again contains a Test2 object which itself has a Test2 object and so on.
The key difference between the two languages regarding your problem is that Java is a language with reference semantics (with the exception of primitive types), and C++ a language with value semantics that allows reference semantics through references and pointers.
Syntax that looks similar in both language has complete different meanings, when in Java you create a reference (Test2 x = new Test2();) the equivalent construct in C++ would be using a pointer (Test2 *x = new Test2();).
A key difference is that it is simple to provide reference semantics on top of value semantics through the use of pointers, but it is impossible to provide value semantics on top of (pure) reference semantics. Some of the implications of this statement include not being able to control the layout of objects in Java in memory or the locality of data (for anything other than primitive types and arrays of primitive types), while on the other direction the finer control of objects in C++ allows you to mimic Java objects.
Re question 2 - if you run this code, you get a StackOverflowException => Yes it creates an inifinite number of objects (well it tries...)
public class Test2 {
private Test2 subject = new Test2(); //Create Test2 object in Test2
public static void main(String[] args) throws Exception {
Test2 t = new Test2();
}
}
subject here is a reference to an instance of Test2. If you try to run it, the code will quickly run out of some resource (probably stack space, maybe heap space).
Why does Java permit the above code to be executed but C++ doesn't?
Since 2011, C++ also allows class members to be initalised in their declarations.
However, it wouldn't allow this case: you can only instantiate complete types, and a class type is incomplete within the class definition, so it would have to be initialised in the constructor, or by a call to a function:
class Test;
Test * make_test();
class Test {
// Test is incomplete, so "new Test" is not possible here
Test * test = make_test();
};
// Test is complete, so we can instantiate it here
Test * make_test() {return new Test;}
Java doesn't have a concept of incomplete types, so the class can be instantiated anywhere you're allowed to instantiate any class.
Does the code above create infinite objects?
Yes, trying to instantiate such a class would throw your program into a recursive death spiral.
If you declare subject as being static, you would get an eager initialization version of the Singleton pattern, which will not get you to out of resources.
since you can have multiple constructors its allowed.
if you only have one constructor this would indeed result in an infinite loop.
public class Test{
private Test a;
public Test(String s){
this.a=new Test();
}
public Test(){
}
}
Related
I'm starting to learn java, and I don't fully understand class variables and instance variables. I've seen some StackOverflow posts about accessing a variable from multiple methods, and most of the answers say to use static class variables. My question is, why can't one just use private instance variables? What are the advantages of using one over the other?
Instance variables are only accessible from instance functions (i. e. from non-static functions). Under the OOP paradigm, most of your variables will likely be instance variables.
Class variables (static) can also be accessed from class functions (static), like your main function.
Say, you have a class called Car. Every instance of this class (say, myFerrari and myBeetle) has its own variables doors, engine, gearbox et cetera. Thus, they are non-static, as are functions like drive (because you are driving an individual car, not the concept of cars).
But you might have a static variable MAX_ALLOWED_PASSENGERS which tells you how many seats a car may have before it's considered a bus instead. This is tied to the concept of cars (i. e. the class), not to any individual car. Thus, it might be static.
As a beginner, depending on your method of learning, you may not yet understand OOP and only write procedural code - which is not what Java is designed for. Thus you may encounter weirdnesses, like code examples where all functions and variables are static. This is a side effect of using Java in an unintended way and its purpose will be clear to you later on.
You can think of a static variable as a shared variable between all instances of the class. It is mostly used when you have a need of common value to be accessible across all objects of the class. Look at below example and execute it. It will clarify things. Please note that I have accessed a static variable with instance which is not the right practice but it is for demonstration purpose only.
public class A{
static int counter=1;
private int value;
public A(int value){
this.value = value;
}
public int getValue(){
return this.value;
}
}
public class B{
public static void main(String[] args){
A a1 = new A(10);
A a2 = new A(12);
System.out.println(a1.value);
System.out.println(a2.value);
System.out.println(A.counter);
System.out.println(a1.counter);
System.out.println(a2.counter);
A.counter=20;
System.out.println(A.counter);
System.out.println(a1.counter);
System.out.println(a2.counter);
}
}
Notice how changing value of counter in class A impacts the result for both variables.
Ok first of all you should in most cases use instance variable.
class variables (static variable) are used when you need one instance across the whole class.
meaning if you have 2 different objects the static variable will be used for both of them, while using instance variable means that each object will hold its own vriable with its own value.
example:
public class Test{
public static int classVar=1;
public int instanceVar;
}
now this code will yield different resulkt based on the variable used:
Test o1=new Test();
o1.instanceVar=1;
Test o2=new Test();
o2.instanceVar=2;
System.out.println("class var object 1"+o1.classVar);//will result in 1 and warn that shoud be used as class level there for as Test.classVar
System.out.println("instance var object 1"+o1.classVar);//will result in 1
System.out.println("class var object 1"+o2.classVar);//will result in 1
System.out.println("instance var object 1"+o2.classVar);//will result in 2
public class Test{
static Test test = new Test();
static {
System.out.println("Test class ...");
}
public static void main(String[] args){
}
}
See code above , class Test will get loaded when main is called and a static instance called test will be constructed , has Test class been loaded already when static Test test = new Test(); is called ? If not , is it safe to do like this ? If loaded, is it safe to construct a new object when class has been loaded but not initialized ?
Edit
Code above seems to be causing much concern about the main method while it is not what I am asking .
public class App{
public static void main(String[] args) {
new Test();
}
}
class Test{
static Test app = new Test();
static{
System.out.println("Test ");
}
{
System.out.println("constructing a Test object ...");
}
}
Code here , am I constructing Test object before Test class initialized ? Is it safe to do so ? Is #Thirler's answer telling that it is not safe but can do so ?
This is allowed, and most of the time this will go fine. However this will allow you to create some constructs which seem fine at a quick glance, but fail. For instance the circular reference below.
public class InitTest {
static InitTest test = new InitTest();
private int count = 0;
public static void main(String[] args) {
}
public InitTest() {
test.count++;
}
}
Here the constructor of the static object calls itself. Since the constructor has not yet finished, the object has not yet been assigned (only finished objects are assigned). And this will cause a NullPointerException on test.count++;
Note that the Java Language Specification is quiet readable, chapter 12 talks about loading classes and specifies the order of initialization (which is the formal name of the phase we are talking about, which gets all static variables initialized). Sections 12.4.1 talks about this some more (though rather vaguely). The bold part (my emphasis) refers to the example above and your question.
The intent is that a class or interface type has a set of initializers
that put it in a consistent state, and that this state is the first
state that is observed by other classes. The static initializers and
class variable initializers are executed in textual order, and may not
refer to class variables declared in the class whose declarations
appear textually after the use, even though these class variables are
in scope (§8.3.3). This restriction is designed to detect, at compile
time, most circular or otherwise malformed initializations.
The fact that initialization code is unrestricted allows examples to
be constructed where the value of a class variable can be observed
when it still has its initial default value, before its initializing
expression is evaluated, but such examples are rare in practice. (Such
examples can be also constructed for instance variable initialization
(§12.5).) The full power of the Java programming language is available
in these initializers; programmers must exercise some care. This power
places an extra burden on code generators, but this burden would arise
in any case because the Java programming language is concurrent
(§12.4.2).
Basically they say: because we want initialization to be strong and not place many restrictions, it is possible, but rare to create situations that wont work.
What is the difference between an object, instance, and reference? They say that they have to create an instance to their application? What does that mean?
An object and an instance are the same thing.
Personally I prefer to use the word "instance" when referring to a specific object of a specific type, for example "an instance of type Foo". But when talking about objects in general I would say "objects" rather than "instances".
A reference either refers to a specific object or else it can be a null reference.
They say that they have to create an instance to their application. What does it mean?
They probably mean you have to write something like this:
Foo foo = new Foo();
If you are unsure what type you should instantiate you should contact the developers of the application and ask for a more complete example.
"instance to an application" means nothing.
"object" and "instance" are the same thing. There is a "class" that defines structure, and instances of that class (obtained with new ClassName()). For example there is the class Car, and there are instance with different properties like mileage, max speed, horse-power, brand, etc.
Reference is, in the Java context, a variable* - it is something pointing to an object/instance. For example, String s = null; - s is a reference, that currently references no instance, but can reference an instance of the String class.
*Jon Skeet made a note about the difference between a variable and a reference. See his comment. It is an important distinction about how Java works when you invoke a method - pass-by-value.
The value of s is a reference. It's very important to distinguish between variables and values, and objects and references.
When you use the keyword new for example JFrame j = new JFrame(); you are creating an instance of the class JFrame.
The new operator instantiates a
class by allocating memory for a new
object and returning a reference to
that memory.
Note: The phrase "instantiating a class" means the same thing as
"creating an object." When you create
an object, you are creating an
"instance" of a class, therefore
"instantiating" a class.
Take a look here
Creating Objects
The types of the Java programming
language are divided into two
categories: primitive types and
reference types.
The reference types
are class types, interface types, and
array types.
There is also a special
null type.
An object is a
dynamically created instance of a
class type or a dynamically created
array.
The values of a reference
type are references to objects.
Refer Types, Values, and Variables for more information
I think that Object = Instance. Reference is a "link" to an Object.
Car c = new Car();
variable c stores a reference to an object of type Car.
Computer c= new Computer()
Here an object is created from the Computer class. A reference named c allows the programmer to access the object.
The main differnece is when you say ClassName obj = null; you are just creating an object for that class. It's not an instance of that class.
This statement will just allot memory for the static meber variables, not for the normal member variables.
But when you say ClassName obj = new ClassName(); you are creating an instance of the class. This staement will allot memory all member variables.
basically object and instance are the two words used interchangeably.
A class is template for an object and an object is an instance of a class.
"creating an instance of a class" how about, "you are taking a class and making a new variable of that class that WILL change depending on an input that changes"
Class in the library called Nacho
variable Libre to hold the "instance" that will change
Nacho Libre = new Nacho(Variable, Scanner Input, or whatever goes here, This is the place that accepts the changes then puts the value in "Libre" on the left side of the equals sign (you know "Nacho Libre = new Nacho(Scanner.in)" "Nacho Libre" is on the left of the = (that's not tech talk, that's my way of explaining it)
I think that is better than saying "instance of type" or "instance of class". Really the point is it just needs to be detailed out more.... "instance of type or class" is not good enough for the beginner..... wow, its like a tongue twister and your brain cannot focus on tongue twisters very well.... that "instance" word is very annoying and the mere sound of it drives me nuts.... it begs for more detail.....it begs to be broken down better. I had to google what "instance" meant just to get my bearings straight..... try saying "instance of class" to your grandma.... yikes!
The Literal meaning of instance is "an example or single occurrence of something." which is very closer to the Instance in Java terminology.
Java follows dynamic loading, which is not like C language where the all code is copied into the RAM at runtime. Lets capture this with an example.
class A
{
int x=0;
public static void main(String [] args)
{
int y=0;
y=y+1;
x=x+1;
}
}
Let us compile and run this code.
step 1: javac A.class (.class file is generated which is byte code)
step 2: java A (.class file is converted into executable code)
During the step 2,The main method and the static elements are loaded into the RAM for execution. In the above scenario, No issue until the line y=y+1. But whenever x=x+1 is executed, the run time error will be thrown as the JVM does not know what the x is which is declared outside the main method(non-static).
So If by some means the content of .class file is available in the memory for CPU to execute, there is no more issue.
This is done through creating the Object and the keyword NEW does this Job.
"The concept of reserving memory in the RAM for the contents of hard disk (here .class file) at runtime is called Instance "
Objects, which are also called instances, are self-contained elements of a program with related features and data. For the most part, you use the class merely to create instances and then work with those instances.
-Definition taken from the book "Sams Teach Yourself Java in 21 days".
Say you have 2 Classes, public class MainClass and public class Class_2 and you want to make an instance of Class_2 in MainClass.
This is a very simple and basic way to do it:
public MainClass() /*******this is the constructor of MainClass*******/
{
Class_2 nameyouwant = new Class_2();
}
I hope this helps!
Instance variable: It must be attached to the object. Instance variables in this class can only be used after instantiating the class
public class Test{
static int a = 13;
int b = 14;
public static void main(String[] args){
int d = new Test().b;
System.out.println(d);
}
}
Instance = memory is allocated at run time for anything that is called instance
Object = memory is allocated at run time for class that is called object
This question already has answers here:
Is there a way to compare lambdas?
(3 answers)
Closed 8 years ago.
The following test fails
#Test
public void test() {
Function<String, Integer> foo = Integer::parseInt;
Function<String, Integer> bar = Integer::parseInt;
assertThat(foo, equalTo(bar));
}
is there any way to make it pass?
edit: I'll try to make it more clear what I'm trying to do.
Lets say I have these classes:
class A {
public int foo(Function<String, Integer> foo) {...}
}
class B {
private final A a; // c'tor injected
public int bar() {
return a.foo(Integer::parseInt);
}
}
now lets say i want to write unit test for B:
#Test
public void test() {
A a = mock(A.class);
B b = new B(a);
b.bar();
verify(a).foo(Integer::parseInt);
}
the problem is that the test fails, because the method references are not equal.
Lambdas are not cached and this seems to be deliberate. There is no way to compare two lambdas to see if they would do the same thing.
You need to do something like
static final Function<String, Integer> parseInt = Integer::parseInt;
#Test
public void test() {
Function<String, Integer> foo = parseInt;
Function<String, Integer> bar = parseInt;
assertThat(foo, equalTo(bar));
}
Answer from Brian Goetz; Is there a way to compare lambdas?
I don't have the API at hand, but Function is an interface. Integer::parseInt seems not to cache, so it will return two different instances, which will be compared by reference => false.
You can make it pass by writing a Comparator, which does what you want.
Have look at the Java Language Specification:
15.27.4. Run-time Evaluation of Lambda Expressions
At run time, evaluation of a lambda expression is similar to evaluation of a class instance creation expression, insofar as normal completion produces a reference to an object. Evaluation of a lambda expression is distinct from execution of the lambda body.
Either a new instance of a class with the properties below is allocated and initialized, or an existing instance of a class with the properties below is referenced.
…
These rules are meant to offer flexibility to implementations of the Java programming language, in that:
A new object need not be allocated on every evaluation.
Objects produced by different lambda expressions need not belong to different classes (if the bodies are identical, for example).
Every object produced by evaluation need not belong to the same class (captured local variables might be inlined, for example).
If an "existing instance" is available, it need not have been created at a previous lambda evaluation (it might have been allocated during the enclosing class's initialization, for example).
In principle, this implies that even a single occurrence of Integer::parseInt in your source code may lead to different object instances (even of different classes) when being evaluated multiple times, not to speak of multiple occurrences of it. The exact decision is left to the actual JRE implementation. See this answer discussing the current behavior of Oracle’s implementation.
It's OK that the test doesn't pass. Lambdas are not objects, they are not subject to properties such as object identity. Instead they are adhoc implementations of functional interfaces.
I believe you shouldn't be expecting your code to rely on the behavior you have described.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why do C# and Java bother with the “new” operator?
Why does java have the new keyword? To create an object of type A, I have to type A a = new A().
Java doesn't have stack allocation, so why couldn't that just be simplified to A a = A()?
Because C++ did it so, I presume. Java was supposed to look superficially like C++, but with a greatly simplified and streamlined language.
In any case, you got a problem there:
class Foo {
private static void A() {
System.out.println("method");
}
public static void main(String[] args) {
A();
}
}
class A {
public A() {
System.out.println("ctor");
}
}
What should happen here? ctor or method?
One obvious drawback to your syntax suggestion is found here:
class A {}
class B extends A {
public A A() { return new B() }
public A foo() { return A(); } //ERK
}
What should the above code in the method foo do? Does it invoke the method named A(), or the constructor of A.
Of course you can now have something like what you want using static imports:
public class A {
public static A A() { return new A(); }
}
This can be brought into scope by import static my.stuff.A.*
That you know you are calling a constructor and not a method.
It is arbitrary. Python constructors work more or less like Java constructors, and are just A(), no new required.
In Java, classes, methods, and variables have different namespaces, which means in any scope you could have one of each with the same name. It'd be ambiguous to say A a = A();, because there could be a method named A(). Sure, Java could look for a method and use a class constructor if it couldn't find a method...but then, it wouldn't be obvious (from looking just at the code) what it does, and the Java people are big on "purity". Plus, if you happened to add a public A A() to your class, that line of code takes on a whole different meaning.
It is arbitrary but one could think of many reasons.
One reason would have to do with the mixing of automatic (stack based) and heap-allocation objects and references for them. You know how in C++ you have to be careful about not taking a pointer to an automatic variable? That's one less headache to worry about.
A second reason is likely that Java is generally designed to have low-cost object allocation and low-cost GC for recent objects (thanks to the use of generational garbage collectors). There is therefore no significant benefit to supporting both types of object allocations.