Initialization and cleanup (5): initialize the array, variable parameter list

First, the array initialization

    But the same type of array, packaged together or substantially the target sequence with a sequence of data type identifier name. Array by square brackets subscript operator [] be defined and used. To define an array, simply type in the name with an empty pair of square brackets can:

int[] a1;

    Square brackets may also be placed behind Identifier:

int a1[];

    Both formats meaning is the same, the former format may be more reasonable, after all, it shows the type is "an int array."

    The compiler does not allow to specify the size of the array. This brings us back to the question about the "Reference". Now it has just a reference to an array (you have been assigned for the quoted enough storage space), but did not allocate any space for the array object itself. In order to create the appropriate storage array, you must write an initialization expression. For arrays, initialization action can appear anywhere in the code, but can also use a special kind of initialization expression that must appear in places to create the array. This special initialization is a value enclosed in curly braces composition. In this case, the allocated memory space (equivalent to using the new) by the compiler is responsible. E.g:

int [] a1 = {1, 2, 3, 4, 5};

    So, why in the absence of a definition of an array of array reference it? int [] a2; in java may be assigning an array to another array, it can be so: a2 = a1; in fact, really do is copy a reference, as just demonstrated the following:

public class ArraysOfPrimitives {
	public static void main(String[] args) {
		int[] a1 = { 1, 2, 3, 4, 5 };
		int[] a2 = a1;
		for (int i = 0; i < a2.length; i++)
			a2[i] = a2[i] + 1;
		for (int i = 0; i < a1.length; i++)
			System.out.println("a1[" + i + "]=" + a1[i]);
	}
}

    It can be seen that the code is given an initial value of a1, a2 but did not; in the present example, a2 is assigned to another array behind. Since a1 and a2 are aliases of the same array, it can be seen by modifying a1 a2 made.

    All arrays (regardless of their elements are objects or basic types) have an intrinsic member, but can not be modified by the array contains within it to know how many elements. This member is length. C and C ++ and the like, java are counted starting with the first array element 0, so the maximum number of the standard can be used are length-1. If beyond this boundary, C and C ++ will "quietly" to accept, and allows you to access all the memory, many statements messy bugs for us. java it can protect you from this problem plagued, once visited subscript out of bounds, run-time errors (ie, abnormal) will appear.

    If in the preparation of the program and can not determine the number of elements in the array in need, then how to do it? It can be used to create new elements in the array directly. Although creating a primitive array, new still work (can not create a single basic types of data new).

import java.util.Arrays;
import java.util.Random;

public class ArrayNew {
	public static void main(String[] args) {
		int[] a;
		Random r = new Random();
		a = new int[r.nextInt(20)];
		System.out.println("length of a=" + a.length);
		System.out.println(Arrays.toString(a));
	}
}

    Size of the array is determined by r.nextInt random () This method returns a value between 0 and output parameters. This indicates that the array is created at run time is indeed carried out. Further, the program output indicates: basic data type value in the array elements are automatically initialized to a null value (for numbers and characters, it is 0; For Boolean is false).

    Arrrays.toString () method belongs java.util standard library, it will generate a one-dimensional array printable version.

    Of course, in the present embodiment, the array may be initialized at the same definitions:

int[] a = new int[r.nextInt(20)];

    If possible, you should try to do so.

    If you create an array of non-primitive type, then you create a reference to the array. Integer to Integer wrapper class, for example, a class which is not basic types:

import java.util.Arrays;
import java.util.Random;

public class ArrayClassObj {
	public static void main(String[] args) {
		Random r = new Random();
		Integer[] a = new Integer[r.nextInt(20)];
		System.out.println("length of a=" + a.length);
		for (int i = 0; i < a.length; i++)
			a[i] = r.nextInt(500);
		System.out.println(Arrays.deepToString(a));
	}
}

    Here, even after using a new array created:

Integer[] a = new Integer[r.nextInt(20)];

    It is just a reference to the array, and until by creating a new Integer object (in this case, is the mechanism created by automatic packaging), and the object is assigned to the reference, considered the end of the initialization process:

a[i] = r.nextInt(500);

    If you forget to create objects, and attempts to use a null reference array, an exception is thrown at run time.

    You can also use a list enclosed in braces to initialize an array of objects. There are two forms:

import java.util.Arrays;

public class ArrayInit {
	public static void main(String[] args) {
		Integer[] a = { new Integer(1), new Integer(2), 3 };
		Integer[] b = new Integer[] { new Integer(1), new Integer(2), 3 };
		System.out.println(Arrays.toString(a));
		System.out.println(Arrays.toString(b));
	}
}

    Although the first form is useful, but it is also more limited, because it can only be used at the array is defined. You can use the second and third form anywhere, even inside the method call. For example, you can create a String object array, passing it to another main () method, to provide parameters for the Replace command is passed to the main () method of line parameters.

public class DynamicArray {
	public static void main(String[] args) {
		Other.main(new String[] { "fiddle", "de", "dum" });
	}
}

class Other {
	public static void main(String[] args) {
		for (String string : args)
			System.out.println(string + " ");
	}
}

    An array as a parameter Other.main () that are created are created at the call method, so you can even provide replaceable parameters when calling.

Second, the variable parameter list

    The second form provides a convenient syntax to create objects and invoke methods to obtain variable parameter list C of the same effect. This parameter can be applied to the case of the number or type unknown. Because all classes are directly or indirectly inherited from the Object class, you can create a method to Object array as a parameter, and call it with the following:

class A {
}

public class VarArgs {
	static void printArray(Object[] args) {
		for (Object object : args)
			System.out.print(object + " ");
		System.out.println();
	}

	public static void main(String[] args) {
		printArray(new Object[] { new Integer(47), new Float(3.14), new Double(11.11) });
		printArray(new Object[] { "one", "two", "three" });
		printArray(new Object[] { new A(), new A(), new A() });
	}
}

    See print () method using Object array as a parameter, and then use the foreach syntax traverse the array, each print object. Standard java library class can output meaningful content, but the object class is established here, just print out the name of the class content and immediately followed by an @ symbol and more hexadecimal digits. Thus, the default behavior is to print the name and address of the object class.

    After java SE5, you can use a variable argument list. E.g:

public class NewVarArgs {
	static void printArray(Object... args) {
		for (Object object : args)
			System.out.print(object + " ");
		System.out.println();
	}

	public static void main(String[] args) {
		printArray(new Object[] { new Integer(47), new Float(3.14), new Double(11.11) });
		printArray(47, 3.14F, 11.11);
		printArray("one", "two", "three");
		printArray(new A(), new A(), new A());
		printArray((Object[]) new Integer[] { 1, 2, 3, 4 });
		printArray();
	}
}

    With variable parameters, no longer have to explicitly write the array syntax when you specify the parameters, the compiler will actually go as you fill the array. You still get is an array, which is why print () can use foreach to iterate the array of reasons. However, this is not just a list of elements from the array to be automatically converted, please note program in the penultimate line, an Integer array (by using automatic packaging created) is transformed into an Object array (in order to remove the compiler warning messages ), and passed to printArray (). Obviously, the compiler will find that he is an array, so no conversion is performed on it. So, if you have a set of things, they can be passed as a list, and if you already have an array, which can put them to accept as a variable parameter list.

    The last line of the program shows that passing 0 to the variable parameter list of parameters is feasible when trailing with optional parameters, this feature can be useful:

public class OptionalTrailingArguments {
	static void f(int required, String... trailing) {
		System.out.print("required: " + required + " ");
		for (String string : trailing)
			System.out.print(string + " ");
		System.out.println();
	}

	public static void main(String[] args) {
		f(1, "one");
		f(2, "two", "three");
		f(0);
	}
}

    The program also shows how you can use a list of variable parameters have outside Object type. Here all the variable parameters must be a String object. Any type of variable parameters in the parameter list, including the basic type. The following example also shows the case where the variable argument list becomes the array, and if there is no element in the list, then the data is converted into a size of 0:

public class VarargType {
	static void f(Character... args) {
		System.out.println(args.getClass());
		System.out.println(" length " + args.length);
	}

	static void g(int... args) {
		System.out.println(args.getClass());
		System.out.println(" length " + args.length);
	}

	public static void main(String[] args) {
		f('a');
		f();
		g(1);
		g();
		System.out.println("int[]: " + new int[0].getClass());
	}
}

    When getClass () method is part of Object, it will produce object class, and such printing, see represent the class type encoded string. Preamble "[" indicates that this is an array type is immediately followed, and followed by the "I" shows the basic type int. To double check, I created an int array in the last line, and prints its type. This also validated the use of variable argument list does not rely on automatic packaging mechanism, and in fact is used basic types.

    However, variable parameter lists and automatic packing mechanism can coexist in harmony, for example:

public class AutoboxingVarargs {
	public static void f(Integer... args) {
		for (Integer integer : args)
			System.out.print(integer + " ");
		System.out.println();
	}

	public static void main(String[] args) {
		f(new Integer(1), new Integer(2));
		f(4, 5, 6, 7, 8, 9);
		f(10, new Integer(11), 12);
	}
}

    Note that you can mix together in a single list in the type parameters, and automatic packaging mechanism to selectively int parameter promoted to Integer.

    The variable parameter list makes heavy-duty process becomes complicated, although at first glance may seem safe enough:

public class OverloadingVarargs {
	static void f(Character... args) {
		System.out.print("first");
		for (Character character : args)
			System.out.print(" " + character);
		System.out.println();
	}

	static void f(Integer... args) {
		System.out.print("second");
		for (Integer integer : args)
			System.out.print(" " + integer);
		System.out.println();
	}

	static void f(Long... args) {
		System.out.println("third");
	}

	public static void main(String[] args) {
		f('a', 'b', 'c');
		f(1);
		f(2, 1);
		f(0);
		f(0L);
		// f();
	}
}

    In each case, the compiler will use automatic packaging mechanism to match the overloaded method, and then call the most obvious way match.

    But when not in use parameter called f (), the compiler will not know which method call, though this error can figure out, but it might make the client programmer by surprise.

    You may be a non-variable parameter by adding a certain method to solve the problem:

public class OverloadingVarargs2 {
	static void f(float i, Character... args) {
		System.out.println("first");
	}

	static void f(Character... args) {
		System.out.println("second");
	}

	public static void main(String[] args) {
		f(1, 'a');
		//f('a', 'b');
	}
}

    If you give these two methods to add a non-variable parameters, you can solve the problem:

public class OverloadingVarargs2 {
	static void f(float i, Character... args) {
		System.out.println("first");
	}

	static void f(char c, Character... args) {
		System.out.println("second");
	}

	public static void main(String[] args) {
		f(1, 'a');
		f('a', 'b');
	}
}

    You should always use only variable parameter lists in the last version of overloaded methods, or are they would not have it.

Published 71 original articles · won praise 2 · Views 6080

Guess you like

Origin blog.csdn.net/qq_40298351/article/details/104075125