How is String arr = new String[] not possible in Java - java

i have trouble understand reference types in Java. So in C++ if we wanna allocate some 1D array dynamicly or single object all we do is:
int *a = new int();
int *a = new int[];
But in Java pointers are not avaliable to programers, references are introduced as some type of pointers but without possibilty of arithemtic operation on the value they hold(point?).
As far as i know every non-primitive data type in Java is of type reference :
String obj; //reference
obj = new String();
And if wanna allocate it something we gotta allocate it on heap, and the obj will hold the adress of that object on heap. So in C++ it would be like :
String *obj = new String();
But for the array we gotta do :
String[] obj = new String[];
And I dont understand why exactly? If obj is already of reference type(simple *ptr) why cant we just do :
String obj = new String[];
How does this exactly work in Java?
Is String[] obj actualy **ptr in C++ or am i missing something?

The reason why you can't write
String obj = new String[];
is that the left-hand side and right-hand side have different types. That's all there is to it. An array of Strings is not a String. A reference to an array of Strings is not a reference to a String.
Maybe more fundamentally, Java is not C++.

Related

Ways of using array in Java

I'm New to Java, I was reading up on how to use array In java. It said to use array in java you have to follow three steps which are Declaration of array, Creating Array and Initialising Array, And I get it But how does the following code work when I haven't followed all of the steps above
int[] array = {1234,234,43,15234,433}
Here I have declared the type of variable I'll be using and named it and directly used it. Unlike the method we usually use In OOP like
int[] array = new int[10];
Does the first way still make array an Object? If yes how?
but will it still be an object as Im not creating an instance like we do with the new keyword
There is no way to prevent creating a new Object unless you explicitly initialise an existing array.
int[] array = {1234,234,43,15234,433}; // creates a new array object every time
is shorthand for
int[] array = new int[] {1234,234,43,15234,433}; // creates a new array object every time
The only way to prevent using a new object is either
int[] array = null; // no new object
or
int[] array = reusedArray; // no new array
array[0] = 1234;
array[1] = 234;
array[2] = 43;
array[3] = 15234;
array[4] = 433;
when we use the "new" keyword what are we exactly telling the compiler
Create a new object on the heap (unless escape analysis can eliminate the object creation) While the Oracle/OpenJDK version 6 to 11 can place some objects on the stack instead of the heap to reduce heap usage, this doesn't apply to arrays AFAIK.
[Added] Is an array an object?
Variables in Java are only primitives or references. If it's not a scalar primitive, it's an object. e.g. Boolean, int[], String, Enum variables are all references to Objects. i.e. String s is not an object.
The first way is just a shorthand for
int[] array = new int[5];
array[0] = 1234;
array[1] = 234;
array[2] = 43;
array[3] = 15234;
array[4] = 433;
Since the following option
int[] array = {1234,234,43,15234,433}
is a lot shorter you can use it whenever you already know the elements of the array at compile time. Please note that in your second case you only created the array, but did not actually fill it with elements.
An array is considered as an object as of the Java Language Specification, Chapter 4.3.1 Object.

Java Object class MYSTERY

While Porting a Game I come to a below statement
Object o = new Object[]{"A","B"};
It's really weird!
But when I try the same with "String" then compiler report me an Error msg
String s = new String[] {"A", "B", "C"}; Error: Type mismatch:
cannot convert from String[] to String
Can you please reveal the Mystery of it ?
You have a trivial error in your code. The fact that every class extends Object makes the error more difficult to find.
Since every class (including arrays) extends Object, conversion from A[] to Object is possible.
You wrote int i = new int[] but that's a mistake, you should have written int[] i.
Probably. Object a = new Object[] is not what you wanted to do.
In Java, Array is an Object too. So you can do
Object o = new Object[]{"A","B"};
or
Object o = new String[]{"A","B"};// But array of String not a String
or
Object o = new int[]{1,2};// But array of int not an int
An "Array" of objects is also an object. But an "Array" of ints is NOT an int.
i.e, an int reference cannot point to an Array but an object reference can.
Object[] obj = new Object[5];// works fine
An object can be anything. It can be an array, it can be an single variable.
Object O = new Object[]{"S","A"};
When you define object you can type cast it to your desired data type.
You can not assign an array of a data type to a single variable of that 'same' datatype.
Every array is an Object[] AND an Object, that's why the following are equally valid:
Object[] o = new Object[]{"A","B"};
Object o = new Object[]{"A","B"};
However a String[] is not a String (and vice-versa) and a int[] is not a int (and vice-versa).
Indeed, you would blend primitives with objects in this latter case.

String array instance assigned to single Object

I came across this Java question:
Which one of the following declaration is false:
a. Object[] myarr1 = new String[3];
b. Object myarr2 = new String[3];
c. String[] myarr3 = new String[3];
d. String myarr3[] = new String[3];
I thought it seems obvious that b is the answer. However, the declaration in b is actually correct upon my checking in Eclipse!
Furthermore, I tried the following:
A. Object[] myarr1 = new String[]{"a1","b1","c1"};
B. Object myarr2 = new String[]{"a2","b2","c2"};
C. String[] myarr3 = new String[]{"a3","b3","c3"};
and printed out the content of each array to study what it actually means by assigning an Object to a String array.
System.out.println(myarr1[0]); //print "a1"
System.out.println(myarr2[0]); //error
System.out.println(myarr3[0]); //print "a3"
System.out.println(myarr1); //print address of myarr1
System.out.println(myarr2); //print address of myarr2
System.out.println(myarr3); //print address of myarr3
It seems myarr1 and myarr3 behave like ordinary String arrays, while myarr2 is different. Debugging to look into the content of myarr2 however showed that the content and structure of myarr2 seems to be the same as myarr1 and myarr3.
Can someone explain to me the significance of this? What are we doing when we use declaration b or B. What is the structure of myarr2 and how do I access its elements or cast it as if it is a String array? I tried (String[])myarr2 but that was an error.
Thanks to all.
They all compile, so they are all correct, as of Java 6.
b. Object myarr2 = new String[3];
This works, because everything you create with the new operator is an object in Java. You could later cast it back to its real type, for example these will work as expected:
Object myarr2 = new String[] { "first", "second" };
String[] real = (String[]) myarr2;
real[1] = "hello";
System.out.println(real[1]); // will output "hello"
System.out.println(((String[])myarr2)[1]); // will output "hello"
d. String myarr3[] = new String[3];
This is valid but discouraged as per this doc:
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
The reason your second print statement emits an error is because the compiler does not know what myarr2 actually is, it just knows it's an Object. For example, you could have had:
Object myarr2 = rand() ? new String[3] : new Dog();
i.e. myarr2 could be some other completely unrelated object as well.
Hence, you cannot index myarr2 as an array. Of course, this can be addressed with a cast:
System.out.println(((String[])myarr2)[0]);

JAVA: why Object [] obj = {new Object[1],new Object[2]} and not other classes?

Hi I have seen that Object [] obj = {new Object[1],new Object[2]} is allowed and I am not sure why it is. If I use other classes instead of Object it's generating errors (like Integer, or ArrayList, or even my classes like Grandpa, Dad and Me)?
Since even an Object[] is an object that's why its not throwing any error. But in reality, what you're actually doing is assigning an array to an Object.
Object[][] obj = {new Object[1],new Object[2]}; // proper way
Object[] obj = {new Object[1],new Object[2]}; // this works because Object[] is treated as an Object
That won't work in the case of String or anything else as each element in a String array has to be a String and not a String array.
String[][] obj = {new String[1],new String[2]}; // proper way as its a 2d array where each element in itself is a 1d array.
String[] obj = {new String[1],new String[2]}; // this won't because each element in String array must be a String
String[] obj = {new String("1"),new String("2")}; // this will work as each element is a string
Your signature satisfied the condition, an array of any Objects.
Object [] obj = {new Object[1],new Object[2]}
Because new Object[1] is an Array and That is also an Object, Since every Class extends Object
obj is just an Object array here. Also Array is a Object too So what is the issue. Object is a base class for any class in Java.
Object [] obj = {Element Should be Objects}
So Array is an Object too.
Object [] obj = {Can have any type of Object because every class by default extends Object Class}
X [] obj = { Array of objects of X Class}
Example:
String[] obj = { Array of String Objects}
Granpa[] gandobj = { Array of Granpa Objects}

Creating an array of objects in Java

I am new to Java and for the time created an array of objects in Java.
I have a class A for example -
A[] arr = new A[4];
But this is only creating pointers (references) to A and not 4 objects. Is this correct? I see that when I try to access functions/variables in the objects created I get a null pointer exception.
To be able to manipulate/access the objects I had to do this:
A[] arr = new A[4];
for (int i = 0; i < 4; i++) {
arr[i] = new A();
}
Is this correct or am I doing something wrong? If this is correct its really odd.
EDIT: I find this odd because in C++ you just say new A[4] and it creates the four objects.
This is correct.
A[] a = new A[4];
...creates 4 A references, similar to doing this:
A a1;
A a2;
A a3;
A a4;
Now you couldn't do a1.someMethod() without allocating a1 like this:
a1 = new A();
Similarly, with the array you need to do this:
a[0] = new A();
...before using it.
This is correct. You can also do :
A[] a = new A[] { new A("args"), new A("other args"), .. };
This syntax can also be used to create and initialize an array anywhere, such as in a method argument:
someMethod( new A[] { new A("args"), new A("other args"), . . } )
Yes, it creates only references, which are set to their default value null. That is why you get a NullPointerException You need to create objects separately and assign the reference. There are 3 steps to create arrays in Java -
Declaration – In this step, we specify the data type and the dimensions of the array that we are going to create. But remember, we don't mention the sizes of dimensions yet. They are left empty.
Instantiation – In this step, we create the array, or allocate memory for the array, using the new keyword. It is in this step that we mention the sizes of the array dimensions.
Initialization – The array is always initialized to the data type’s default value. But we can make our own initializations.
Declaring Arrays In Java
This is how we declare a one-dimensional array in Java –
int[] array;
int array[];
Oracle recommends that you use the former syntax for declaring arrays.
Here are some other examples of legal declarations –
// One Dimensional Arrays
int[] intArray; // Good
double[] doubleArray;
// One Dimensional Arrays
byte byteArray[]; // Ugly!
long longArray[];
// Two Dimensional Arrays
int[][] int2DArray; // Good
double[][] double2DArray;
// Two Dimensional Arrays
byte[] byte2DArray[]; // Ugly
long[] long2DArray[];
And these are some examples of illegal declarations –
int[5] intArray; // Don't mention size!
double{} doubleArray; // Square Brackets please!
Instantiation
This is how we “instantiate”, or allocate memory for an array –
int[] array = new int[5];
When the JVM encounters the new keyword, it understands that it must allocate memory for something. And by specifying int[5], we mean that we want an array of ints, of size 5.
So, the JVM creates the memory and assigns the reference of the newly allocated memory to array which a “reference” of type int[]
Initialization
Using a Loop – Using a for loop to initialize elements of an array is the most common way to get the array going. There’s no need to run a for loop if you are going to assign the default value itself, because JVM does it for you.
All in One..! – We can Declare, Instantiate and Initialize our array in one go. Here’s the syntax –
int[] arr = {1, 2, 3, 4, 5};
Here, we don’t mention the size, because JVM can see that we are giving 5 values.
So, until we instantiate the references remain null. I hope my answer has helped you..! :)
Source - Arrays in Java
You are correct. Aside from that if we want to create array of specific size filled with elements provided by some "factory", since Java 8 (which introduces stream API) we can use this one-liner:
A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
Stream.generate(() -> new A()) is like factory for separate A elements created in a way described by lambda, () -> new A() which is implementation of Supplier<A> - it describe how each new A instances should be created.
limit(4) sets amount of elements which stream will generate
toArray(A[]::new) (can also be rewritten as toArray(size -> new A[size])) - it lets us decide/describe type of array which should be returned.
For some primitive types you can use DoubleStream, IntStream, LongStream which additionally provide generators like range rangeClosed and few others.
Here is the clear example of creating array of 10 employee objects, with a constructor that takes parameter:
public class MainClass
{
public static void main(String args[])
{
System.out.println("Hello, World!");
//step1 : first create array of 10 elements that holds object addresses.
Emp[] employees = new Emp[10];
//step2 : now create objects in a loop.
for(int i=0; i<employees.length; i++){
employees[i] = new Emp(i+1);//this will call constructor.
}
}
}
class Emp{
int eno;
public Emp(int no){
eno = no;
System.out.println("emp constructor called..eno is.."+eno);
}
}
The genaral form to declare a new array in java is as follows:
type arrayName[] = new type[numberOfElements];
Where type is a primitive type or Object. numberOfElements is the number of elements you will store into the array and this value can’t change because Java does not support dynamic arrays (if you need a flexible and dynamic structure for holding objects you may want to use some of the Java collections).
Lets initialize an array to store the salaries of all employees in a small company of 5 people:
int salaries[] = new int[5];
The type of the array (in this case int) applies to all values in the array. You can not mix types in one array.
Now that we have our salaries array initialized we want to put some values into it. We can do this either during the initialization like this:
int salaries[] = {50000, 75340, 110500, 98270, 39400};
Or to do it at a later point like this:
salaries[0] = 50000;
salaries[1] = 75340;
salaries[2] = 110500;
salaries[3] = 98270;
salaries[4] = 39400;
More visual example of array creation:
To learn more about Arrays, check out the guide.
Yes it is correct in Java there are several steps to make an array of objects:
Declaring and then Instantiating (Create memory to store '4' objects):
A[ ] arr = new A[4];
Initializing the Objects (In this case you can Initialize 4 objects of class A)
arr[0] = new A();
arr[1] = new A();
arr[2] = new A();
arr[3] = new A();
or
for( int i=0; i<4; i++ )
arr[i] = new A();
Now you can start calling existing methods from the objects you just made etc.
For example:
int x = arr[1].getNumber();
or
arr[1].setNumber(x);
For generic class it is necessary to create a wrapper class.
For Example:
Set<String>[] sets = new HashSet<>[10]
results in: "Cannot create a generic array"
Use instead:
class SetOfS{public Set<String> set = new HashSet<>();}
SetOfS[] sets = new SetOfS[10];
Suppose the class A is such:
class A{
int rollno;
int DOB;
}
and you want to create an array of the objects for the class A. So you do like this,
A[] arr = new A[4]; //Statement 1
for (int i = 0; i < 4; i++) {
arr[i] = new A(); //Statement 2
}
which is absolutely correct.
Here A is the class and in Statement 1 Class A is a datatype of the array. When this statement gets executed because of the new keyword an object is created and dynamically memory is allocated to it which will be equal to the space required for the 4 blocks of datatype A i.e, ( for one block in the array space required is 8 bytes (4+4), I am assuming int takes 4 bytes of space. therefore total space allocated is 4*4 bytes for the array ).
Then the reference of the object is given to the arr variable. Here important point to note is that Statement 1 has nothing to do with creating an object for class A ,no object is created for this class it is only used as a datatype which gives the size of the class A required for the memory allocation of the array.
Then when for loop is run and Statement 2 is executed JVM now allocates the memory for the Class A (i.e creates an object) and gives its reference to the arr[i]. Every time the loop is called an object is created and the reference of it is given to arr[i].
Thus, arr[0] which holds a space of 8 bytes is given the reference of the object of the Class A and everytime loop is run new object is created and reference is given to that object so that it can now access the data in that object .

Categories

Resources