Basics of Java Syntax - ilya-khadykin/notes-outdated GitHub Wiki
Variables (1)
An object stores its state in fields. In the Java programming language, the terms "field" and "variable" are both used; this is a common source of confusion among new developers, since both often seem to refer to the same thing.
The Java programming language defines the following kinds of variables:
-
Instance Variables (Non-Static Fields) - Technically speaking, objects store their individual states in "non-static fields", that is, fields declared without the
static
keyword. Non-static fields are also known as instance variables because their values are unique to each instance of a class (to each object, in other words); thecurrentSpeed
of one bicycle is independent from thecurrentSpeed
of another. -
Class Variables (Static Fields) - A class variable is any field declared with the
static
modifier; this tells the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated. A field defining the number of gears for a particular kind of bicycle could be marked as static since conceptually the same number of gears will apply to all instances. The codestatic int numGears = 6;
would create such astatic
field. Additionally, the keywordfinal
could be added to indicate that the number of gears will never change. - Local Variables - Similar to how an object stores its state in fields, a method will often store its temporary state in local variables. The syntax for declaring a local variable is similar to declaring a field (for example, int count = 0;). There is no special keyword designating a variable as local; that determination comes entirely from the location in which the variable is declared — which is between the opening and closing braces of a method. As such, local variables are only visible to the methods in which they are declared; they are not accessible from the rest of the class.
-
Parameters - the signature for the
main
method ispublic static void main(String[] args)
. Here, theargs
variable is the parameter to this method. The important thing to remember is that parameters are always classified as "variables" not "fields". This applies to other parameter-accepting constructs as well (such as constructors and exception handlers)
The rules and conventions for naming your variables can be summarized as follows:
- Variable names are case-sensitive. A variable's name can be any legal identifier — an unlimited-length sequence of Unicode letters and digits, beginning with a letter, the dollar sign "$", or the underscore character "". The convention, however, is to always begin your variable names with a letter, not "$" or "". Additionally, the dollar sign character, by convention, is never used at all. You may find some situations where auto-generated names will contain the dollar sign, but your variable names should always avoid using it. A similar convention exists for the underscore character; while it's technically legal to begin your variable's name with "_", this practice is discouraged. White space is not permitted.
- Subsequent characters may be letters, digits, dollar signs, or underscore characters. Conventions (and common sense) apply to this rule as well. When choosing a name for your variables, use full words instead of cryptic abbreviations. Doing so will make your code easier to read and understand. In many cases it will also make your code self-documenting; fields named
cadence
,speed
, andgear
, for example, are much more intuitive than abbreviated versions, such ass
,c
, andg
. Also keep in mind that the name you choose must not be a keyword or reserved word. - If the name you choose consists of only one word, spell that word in all lowercase letters. If it consists of more than one word, capitalize the first letter of each subsequent word. The names
gearRatio
andcurrentGear
are prime examples of this convention. If your variable stores a constant value, such asstatic final int NUM_GEARS = 6
, the convention changes slightly, capitalizing every letter and separating subsequent words with the underscore character. By convention, the underscore character is never used elsewhere.
A data type is a set of values and a set of operations on those values
The Java programming language is statically-typed, which means that all variables must first be declared before they can be used. The scope of a variable is the part of the program where it is defined.
The Java programming language supports eight primitive data types. A primitive type is predefined by the language and is named by a reserved keyword. Primitive values do not share state with other primitive values. The eight primitive data types supported by the Java programming language are:
-
byte: The
byte
data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). Thebyte
data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place ofint
where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation. -
short: The
short
data type is a 16-bit signed two's complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive). As withbyte
, the same guidelines apply: you can use ashort
to save memory in large arrays, in situations where the memory savings actually matters. -
int: By default, the
int
data type is a 32-bit signed two's complement integer, which has a minimum value of -2^31 and a maximum value of 2^31-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 2^32-1. Use theInteger
class to use int data type as an unsigned integer. Static methods likecompareUnsigned
,divideUnsigned
etc have been added to theInteger
class to support the arithmetic operations for unsigned integers. -
long: The
long
data type is a 64-bit two's complement integer. The signed long has a minimum value of -2^63 and a maximum value of 2^63-1. In Java SE 8 and later, you can use thelong
data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 2^64-1. Use this data type when you need a range of values wider than those provided byint
. TheLong
class also contains methods likecompareUnsigned
,divideUnsigned
etc to support arithmetic operations for unsigned long. -
float: The
float
data type is a single-precision 32-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. As with the recommendations forbyte
andshort
, use afloat
(instead ofdouble
) if you need to save memory in large arrays of floating point numbers. This data type should never be used for precise values, such as currency. For that, you will need to use thejava.math.BigDecimal
class instead. -
double: The
double
data type is a double-precision 64-bit IEEE 754 floating point. Its range of values is beyond the scope of this discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language Specification. For decimal values, this data type is generally the default choice. As mentioned above, this data type should never be used for precise values, such as currency. -
boolean: The
boolean
data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its "size" isn't something that's precisely defined. -
char: The char data type is a single 16-bit Unicode character. It has a minimum value of '
\u0000
' (or 0) and a maximum value of '\uffff
' (or 65,535 inclusive).
In addition to the eight primitive data types listed above, the Java programming language also provides special support for character strings via the java.lang.String class. Enclosing your character string within double quotes will automatically create a new String
object; for example, String s = "this is a string"
;. String
objects are immutable, which means that once created, their values cannot be changed. The String
class is not technically a primitive data type, but considering the special support given to it by the language, you'll probably tend to think of it as such.
It's not always necessary to assign a value when a field is declared. Fields that are declared but not initialized will be set to a reasonable default by the compiler. Generally speaking, this default will be zero or null, depending on the data type. Relying on such default values, however, is generally considered bad programming style.
The following chart summarizes the default values for the above data types.
Data Type | Default Value (for fields) |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
char | '\u0000' |
String (or any object) | null |
boolean | false |
Local variables are slightly different; the compiler never assigns a default value to an uninitialized local variable. If you cannot initialize your local variable where it is declared, make sure to assign it a value before you attempt to use it. Accessing an uninitialized local variable will result in a compile-time error.
You may have noticed that the new keyword isn't used when initializing a variable of a primitive type. Primitive types are special data types built into the language; they are not objects created from a class. A literal is the source code representation of a fixed value; literals are represented directly in your code without requiring computation. As shown below, it's possible to assign a literal to a variable of a primitive type:
boolean result = true;
char capitalC = 'C';
byte b = 100;
short s = 10000;
int i = 100000;
Literals of types char and String may contain any Unicode (UTF-16) characters. If your editor and file system allow it, you can use such characters directly in your code. If not, you can use a "Unicode escape" such as '\u0108' (capital C with circumflex), or "S\u00ED Se\u00F1or" (Sí Señor in Spanish). Always use 'single quotes' for char literals and "double quotes" for String literals. Unicode escape sequences may be used elsewhere in a program (such as in field names, for example), not just in char or String literals.
The Java programming language also supports a few special escape sequences for char and String literals: \b (backspace), \t (tab), \n (line feed), \f (form feed), \r (carriage return), " (double quote), ' (single quote), and \ (backslash).
There's also a special null literal that can be used as a value for any reference type. null may be assigned to any variable, except variables of primitive types. There's little you can do with a null value beyond testing for its presence. Therefore, null is often used in programs as a marker to indicate that some object is unavailable.
Finally, there's also a special kind of literal called a class literal, formed by taking a type name and appending ".class
"; for example, String.class
. This refers to the object (of type Class) that represents the type itself.
In Java SE 7 and later, any number of underscore characters (_) can appear anywhere between digits in a numerical literal. This feature enables you, for example. to separate groups of digits in numeric literals, which can improve the readability of your code.
For instance, if your code contains numbers with many digits, you can use an underscore character to separate digits in groups of three, similar to how you would use a punctuation mark like a comma, or a space, as a separator.
The following example shows other ways you can use the underscore in numeric literals:
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;
A Java program manipulates variables that are named with identifiers. Each variable is associated with a data type and stores one of the permissible data-type values. We use expressions to apply the operations associated with each type. (2)
public class Variables {
public static void main(String[] args) {
// <variable_type> <varibale_name> = <value>
// Naming convention - exampleName
// numeric values, all signed
byte aByte = 127; // 8 bits
short aShort = 037654; // 16 bits
int anInteger = 123456; // 32 bits
long aLong = 0xCAFE; // 64 bits
// floating point numbers
float aFloat = 99.9F; // 32 bits, real number with single precision
double aDouble = 98.0E+99;
// unsigned number represents a character
// coded using Unicode
// use only '', "" is used for Strings
char aCharacter = 'A'; // behaves like 16 bits
aCharacter = '\u0041'; // hexadecimal literal
aCharacter = '\n'; // newline
// logical value; true or false
boolean aBoolean = true; // behaves like one bit
}
}
The following table summarizes the set of values and most common operations on those values for Java's int
, double
, boolean
, and char
data types. (2)
public class Operators {
public static void main(String[] args) {
int i = 0;
short aShort = 1;
long aLong = 0xCAFEBABE;
i++; // i = i + 1;
i /= 2; i = i/2;
aShort = (short) aLong; // can 'cast' to force the assignment
}
}
- equal (
==
) - not equal (
!=
) - less than (
<
) - less than or equal (
<=
) - greater than (
>
) - greater than or equal (
>=
)
public class Conditions {
public static void main(String[] args) {
int a = 100;
int b = 199;
if (a < b) {
System.out.println(a + " is less than " + b);
} else {
System.out.println(a + " is greater than " + b);
}
switch (a) {
case 98:
case 99:
System.out.println("a is 98 or 99");
break;
case 100:
System.out.println("a is 100");
break;
default:
System.out.println("a is something else");
break;
}
int a = 0;
while (a < 10) {
System.out.println("a is " + a);
a++;
}
do {
System.out.println("a is " + a);
a++;
} while (a < 10);
for (int x = 0; x < 10; x++) { // x is scoped only inside the loop
System.out.println("x is " + x);
}
for ( ; a < 20; ) { // equivalent to while (a < 20)
System.out.println("a is " + a++);
}
for (;;) {
System.out.println("a is " + a++);
if (a > 25) {
break; // stop execution of the loop and continue the execution
}
}
}
}
The following table illustrates different kinds of Java statements. (2)
An array is a container object that holds a fixed number of values of a single type. The length of an array is established when the array is created. After creation, its length is fixed.
Once we create an array, its size is fixed. A program can refer to the length of an array a[] with the code a.length. Java does automatic bounds checking—if you access an array with an illegal index your program will terminate with an ArrayIndexOutOfBoundsException
.
As with variables of other types, the declaration does not actually create an array; it simply tells the compiler that this variable will hold an array of the specified type.
Similarly, you can declare arrays of other types:
byte[] anArrayOfBytes;
short[] anArrayOfShorts;
long[] anArrayOfLongs;
float[] anArrayOfFloats;
double[] anArrayOfDoubles;
boolean[] anArrayOfBooleans;
char[] anArrayOfChars;
String[] anArrayOfStrings;
public class Arrays {
public static void main(String[] args) {
int[] values = { 1, 2, 3, 4, 5, 6, 13, 21, 34 };
System.out.println("The fifth element of values is " + values[4]);
System.out.println("There are " + values.length + " elements in values");
for (int idx = 0; idx < values.length; idx++) {
System.out.println("values[" + idx + "] is " + values[idx]);
}
int[] moreValues = new int[20];
System.arraycopy(values, 0, moreValues, 0, values.length);
int [][] raggedMatrix = {
{ 1, 2, 3 },
{ 4, 5 },
{ 6, 7, 8, 9 }
};
System.out.println("raggedMatrix[0][2] is " + raggedMatrix[0][2]);
}
}
Aliasing. An array name refers to the whole array—if we assign one array name to another, then both refer to the same array, as illustrated in the following code fragment:
int[] a = new int[N];
...
a[i] = 1234;
...
int[] b = a;
...
b[i] = 5678; // a[i] is now 5678.
You can also declare an array of arrays (also known as a multidimensional array) by using two or more sets of brackets, such as String[][] names
. Each element, therefore, must be accessed by a corresponding number of index values.
In the Java programming language, a multidimensional array is an array whose components are themselves arrays. This is unlike arrays in C or Fortran. A consequence of this is that the rows are allowed to vary in length, as shown in the following MultiDimArrayDemo program:
class MultiDimArrayDemo {
public static void main(String[] args) {
String[][] names = {
{"Mr. ", "Mrs. ", "Ms. "},
{"Smith", "Jones"}
};
// Mr. Smith
System.out.println(names[0][0] + names[1][0]);
// Ms. Jones
System.out.println(names[0][2] + names[1][1]);
}
}
Finally, you can use the built-in length property to determine the size of any array. The following code prints the array's size to standard output:
System.out.println(anArray.length);
The System class has an arraycopy method that you can use to efficiently copy data from one array into another:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) The two Object arguments specify the array to copy from and the array to copy to. The three int arguments specify the starting position in the source array, the starting position in the destination array, and the number of array elements to copy.
The following program, ArrayCopyDemo, declares an array of char elements, spelling the word "decaffeinated." It uses the System.arraycopy method to copy a subsequence of array components into a second array:
class ArrayCopyDemo {
public static void main(String[] args) {
char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',
'i', 'n', 'a', 't', 'e', 'd' };
char[] copyTo = new char[7];
System.arraycopy(copyFrom, 2, copyTo, 0, 7);
System.out.println(new String(copyTo));
}
}
For your convenience, Java SE provides several methods for performing array manipulations (common tasks, such as copying, sorting and searching arrays) in the java.util.Arrays class
.
Some other useful operations provided by methods in the java.util.Arrays class, are:
- Searching an array for a specific value to get the index at which it is placed (the
binarySearch
method). - Comparing two arrays to determine if they are equal or not (the
equals
method). - Filling an array to place a specific value at each index (the
fill
method). - Sorting an array into ascending order. This can be done either sequentially, using the
sort
method, or concurrently, using theparallelSort
method introduced in Java SE 8. Parallel sorting of large arrays on multiprocessor systems is faster than sequential array sorting.
With static
you declare a class method or variable
public class Methods {
public static float average(float[] fa) {
float sum = 0.0F;
for (int idx = 0; idx < fa.length; idx++) {
sum += fa[idx];
}
return sum / fa.length;
}
// initial code
public static void main(String[] args) {
float[] fal = { 1.2F, 3.2F, 5.9F, 9.6F };
float sum = 0.0F;
for (int idx = 0; idx < fal.length; idx++) {
sum += fal[idx];
}
float average = sum / fal.length;
System.out.println("Average of the numbers is " + average);
float[] fa2 = { 19.0F, 9.9F, 5.9F, 9.6F, 7.8F, 2.8F };
sum = 0.0F;
for (int idx = 0; idx < fa2.length; idx++) {
sum += fa2[idx];
}
average = sum / fa2.length;
System.out.println("Average of the numbers is " + average);
// refactored code
System.out.println("Average of the first set of numbers is " + average(fal));
System.out.println("Average of the first set of numbers is " + average(fa2));
}
}
/*
* Item.java
*/
package structures1;
public class Item {
public String name;
public int price;
public int quantity;
}
/*
* Structure1.java
*/
package structures1;
public class Structures1 {
public static void main(String[] args) {
Item an Item = new Item();
anItem.name = "Frosty Crunches";
anItem.price = 250;
anItem.quantity
}
}
Date Data Structure (1)
/*
* Date.java
*/
package date1;
public class Date {
public int day;
public int month;
public int year;
public boolean isLeapYear(int year) {
return (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0);
}
public int daysInMonth(int month, int year) {
int rv;
switch(month) {
case 9: // Thirty days hath September
case 4: // April
case 6: // June
case 11: // and November
rv = 30;
break;
case 2:
if (isLeapYear(year)) {
rv = 29;
} else {
rv = 28;
}
break;
default:
rv = 31;
break;
}
return rv;
}
public void nextDay() {
int dayCount = daysInMonth(this.month, this.year);
this.day++;
if (this.day > dayCount) {
this.day = 1;
this.month++;
if (this.month > 12) {
this.month = 1;
this.year++;
}
}
}
// Constructor
public Date(int m, ind d, int, y) {
this.day = d;
this.month = m;
this.year = y;
}
}
/*
* Date1.java
*/
package date1;
public class Date1 {
public static void main(String[] args) {
Date meetingDate = new Date(2, 29, 2012);
System.out.println("Meeting will be on "
+ meetingDate.month + "/"
+ meetingDate.day + "/"
+ meetingDate.year);
}
}