The Java programming language is...
General-purpose: It is designed to be used for writing software in a wide variety of application domains, and lacks specialized features for any specific domain.
Class-based: Its object structure is defined in classes. Class instances always have those fields and methods specified in their class definitions (see Classes and Objects). This is in contrast to non-class-based languages such as JavaScript.
Statically-typed: the compiler checks at compile time that variable types are respected. For example, if a method expects an argument of type String
, that argument must in fact be a string when the method is called.
Object-oriented: most things in a Java program are class instances, i.e. bundles of state (fields) and behavior (methods which operate on data and form the object's interface to the outside world).
Portable: It can be compiled on any platform with javac
and the resultant class files can run on any platform that has a JVM.
Java is intended to let application developers "write once, run anywhere" (WORA), meaning that compiled Java code can run on all platforms that support Java without the need for recompilation.
Java code is compiled to bytecode (the .class
files) which in turn get interpreted by the Java Virtual Machine (JVM). In theory, bytecode created by one Java compiler should run the same way on any JVM, even on a different kind of computer. The JVM might (and in real-world programs will) choose to compile into native machine commands the parts of the bytecode that are executed often. This is called "Just-in-time (JIT) compilation".
There are three "editions" of Java defined by Sun / Oracle:
There is a separate topic on Java SE / EE / ME editions.
Each edition has multiple versions. The Java SE versions are listed below.
There is a separate topic on Installing Java (Standard Edition).
There are separate topics on:
Here are links to subjects to continue learning and understanding the Java programming language. These subjects are the basics of the Java programming to get you started.
While Java does not have any support for testing in the standard library, there are 3rd-party libraries that are designed to support testing. The two most popular unit testing libraries are:
1. In Versions section the end-of-life (free) date is when Oracle will stop posting further updates of Java SE to its public download sites. Customers who need continued access to critical bug fixes and security fixes as well as general maintenance for Java SE can get long term support through Oracle Java SE Support.
Inheritance is often combined with generics so that the base class has one or more type parameters. See Creating a Generic Class.
Collections are objects that can store collections of other objects inside of them. You can specify the type of data stored in a collection using Generics.
Collections generally use the java.util
or java.util.concurrent
namespaces.
Java 1.4.2 and below do not support generics. As such, you can not specify the type parameters that a collection contains. In addition to not having type safety, you must also use casts to get the correct type back from a collection.
In addition to Collection<E>
, there are multiple major types of collections, some of which have subtypes.
List<E>
is an ordered collection of objects. It is similar to an array, but does not define a size limit. Implementations will usually grow in size internally to accomodate new elements.Set<E>
is a collection of objects that does not allow duplicates.
SortedSet<E>
is a Set<E>
that also specifies element ordering.Map<K,V>
is a collection of key/value pairs.
SortedMap<K,V>
is a Map<K,V>
that also specifies element ordering.Java 5 adds in a new collection type:
Queue<E>
is a collection of elements meant to be processed in a specific order. The implementation specifies whether this is FIFO or LIFO. This obsoletes the Stack
class.Java 6 adds in some new subtypes of collections.
NavigableSet<E>
is a Set<E>
with special navigation methods built in.NavigableMap<K,V>
is a Map<K,V>
with special navigation methods built in.Deque<E>
is a Queue<E>
that can be read from either end.Note that the above items are all interfaces. In order to use them, you must find the appropriate implementing classes, such as ArrayList
, HashSet
, HashMap
, or PriorityQueue
.
Each type of collection has multiple implementations that have different performance metrics and use cases.
Note that the Liskov Substitution Principle applies to the collection subtypes. That is, a SortedSet<E>
can be passed to a function expecting a Set<E>
. It is also useful to read about Bounded Parameters in the Generics section for more information on how to use collections with class inheritance.
If you want to create your own collections, it may be easier to inherit one of the abstract classes (such as AbstractList
) instead of implementing the interface.
Prior to 1.2, you had to use the following classes/interfaces instead:
Vector
instead of ArrayList
Dictionary
instead of Map
. Note that Dictionary is also an abstract class rather than an interface.Hashtable
instead of HashMap
These classes are obsolete and should not be used in modern code.
Generics are implemented in Java through Type erasure, which means that during runtime the Type information specified in the instantiation of a generic class is not available. For example, the statement List<String> names = new ArrayList<>();
produces a list object from which the element type String
cannot be recovered at runtime. However, if the list is stored in a field of type List<String>
, or passed to a method/constructor parameter of this same type, or returned from a method of that return type, then the full type information can be recovered at runtime through the Java Reflection API.
This also means that when casting to a generic type (e.g.: (List<String>) list
), the cast is an unchecked cast. Because the parameter <String>
is erased, the JVM cannot check if a cast from a List<?>
to a List<String>
is correct; the JVM only sees a cast for List
to List
at runtime.
A map is an object which store keys with an associated value for each key. A key and its value are sometimes called a key/value pair or an entry. Maps typically provide these features:
The most commonly used map implementation is HashMap. It works well with keys that are strings or numbers.
Plain maps such as HashMap are unordered. Iterating through key/value pairs may return individual entries in any order. If you need to iterate through map entries in a controlled fashion, you should look at the following:
Sorted maps such as TreeMap will iterate through keys in their natural order (or in an order that you can specify, by providing a Comparator). For example, a sorted map using numbers as keys would be expected to iterate through its entries in numeric order.
LinkedHashMap permits iterating through entries in the same order that they were inserted into the map, or by the order of most recently accessed.
Since Java strings are immutable, all methods which manipulate a String
will return a new String
object. They do not change the original String
. This includes to substring and replacement methods that C and C++ programers would expect to mutate the target String
object.
Use a StringBuilder
instead of String
if you want to concatenate more than two String
objects whose values cannot be determined at compile-time. This technique is more performant than creating new String
objects and concatenating them because StringBuilder
is mutable.
StringBuffer
can also be used to concatenate String
objects. However, this class is less performant because it is designed to be thread-safe, and acquires a mutex before each operation. Since you almost never need thread-safety when concatenating strings, it is best to use StringBuilder
.
If you can express a string concatenation as a single expression, then it is better to use the +
operator. The Java compiler will convert an expression containing +
concatenations into an efficient sequence of operations using either String.concat(...)
or StringBuilder
. The advice to use StringBuilder
explicitly only applies when the concatenation involves a multiple expressions.
Don't store sensitive information in strings. If someone is able to obtain a memory dump of your running application, then they will be able to find all of the existing String
objects and read their contents. This includes String
objects that are unreachable and are awaiting garbage collection. If this is a concern, you will need to wipe sensitive string data as soon as you are done with it. You cannot do this with String
objects since they are immutable. Therefore, it is advisable to use a char[]
objects to hold sensitive character data, and wipe them (e.g. overwrite them with '\000'
characters) when you are done.
All String
instances are created on the heap, even instances that correspond to string literals. The special thing about string literals is that the JVM ensures that all literals that are equal (i.e. that consists of the same characters) are represented by a single String
object (this behavior is specified in JLS).
This is implemented by JVM class loaders. When a class loader loads a class, it scans for string literals that are used in the class definition, each time it sees one, it checks if there is already a record in the string pool for this literal (using the literal as a key). If there is already an entry for the literal, the reference to a String
instance stored as the pair for that literal is used. Otherwise, a new String
instance is created and a reference to the instance is stored for the literal (used as a key) in the string pool. (Also see string interning).
The string pool is held in the Java heap, and is subject to normal garbage collection.
In releases of Java before Java 7, the string pool was held in a special part of the heap known as "PermGen". This part was only collected occasionally.
In Java 7, the string pool was moved off from "PermGen".
Note that string literals are implicitly reachable from any method that uses them. This means that the corresponding String
objects can only be garbage collected if the code itself is garbage collected.
Up until Java 8, String
objects are implemented as a UTF-16 char array (2 bytes per char). There is a proposal in Java 9 to implement String
as a byte array with an encoding flag field to note if the string is encoded as bytes (LATIN-1) or chars (UTF-16).
Note that most of the time you do NOT use InputStream
s directly but use BufferedStream
s, or similar. This is because InputStream
reads from the source every time the read method is called. This can cause significant CPU usage in context switches into and out of the kernel.
Below is a table summarizing the interaction between sub-class and super-class.
- | SUPER_CLASS-INSTANCE-METHOD | SUPER_CLASS-STATIC-METHOD |
---|---|---|
SUB_CLASS-INSTANCE-METHOD | overrides | generates-compiletime-error |
SUB_CLASS-STATIC-METHOD | generates-compiletime-error | hides |
Below is a table summarizing the interaction between interface and implementing-class.
- | INTERFACE-DEFAULT-METHOD | INTERFACE-STATIC-METHOD |
---|---|---|
IMPL_CLASS-INSTANCE-METHOD | overrides | hides |
IMPL_CLASS-STATIC-METHOD | generates-compiletime-error | hides |
All control structures, unless otherwise noted, make use of block statements. These are denoted by curly braces {}
.
This differs from normal statements, which do not require curly braces, but also come with a stiff caveat in that only the line immediately following the previous statement would be considered.
Thus, it is perfectly valid to write any of these control structures without curly braces, so long as only one statement follows the beginning, but it is strongly discouraged, as it can lead to buggy implementations, or broken code.
Example:
// valid, but discouraged
Scanner scan = new Scanner(System.in);
int val = scan.nextInt();
if(val % 2 == 0)
System.out.println("Val was even!");
// invalid; will not compile
// note the misleading indentation here
for(int i = 0; i < 10; i++)
System.out.println(i);
System.out.println("i is currently: " + i);
Related topic(s) on StackOverflow:
From the Java tutorial:
Access level modifiers determine whether other classes can use a particular field or invoke a particular method. There are two levels of access control:
public
, or package-private (no explicit modifier).public
, private
, protected
, or package-private (no explicit modifier).A class may be declared with the modifier public
, in which case that class is visible to all classes everywhere. If a class has no modifier (the default, also known as package-private), it is visible only within its own package.
At the member level, you can also use the public
modifier or no modifier (package-private) just as with top-level classes, and with the same meaning. For members, there are two additional access modifiers: private
and protected
. The private
modifier specifies that the member can only be accessed in its own class. The protected
modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
The following table shows the access to members permitted by each modifier.
Access Levels:
Modifier | Class | Package | Subclass | World |
---|---|---|---|---|
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
no modifier | Y | Y | N | N |
private | Y | N | N | N |
You will need to add the following imports before you can use Regex:
import java.util.regex.Matcher
import java.util.regex.Pattern
In java, a backslash is escaped with a double backslash, so a backslash in the regex string should be inputted as a double backslash. If you need to escape a double backslash (to match a single backslash with the regex, you need to input it as a quadruple backslash.
Character | Description |
---|---|
* | Match the preceding character or subexpression 0 or more times |
+ | Match the preceding character or subexpression 1 or more times |
? | Match the preceding character or subexpression 0 or 1 times |
The regex topic contains more information about regular expressions.
Autoboxing can have performance issues when used frequently in your code.
Javadoc is a tool included with the JDK that allows in-code comments to be converted to an HTML documentation. The Java API Specification was generated using Javadoc. The same is true for much of the documentation of 3rd-party libraries.
Pitfalls
Using the XJC tool available in the JDK, java code for a xml structure described in a xml schema (.xsd
file) can be automatically generated, see XJC topic.
Java has 8 primitive data types, namely boolean
, byte
, short
, char
, int
, long
, float
and double
. (All other types are reference types. This includes all array types, and built-in object types / classes that have special significance in the Java language; e.g. String
, Class
and Throwable
and its subclasses.)
The result of all operations (addition, subtraction, multiplication, etc) on a primitive type is at least an int
, thus adding a short
to a short
produces an int
, as does adding a byte
to a byte
, or a char
to a char
. If you want to assign the result of that back to a value of the same type, you must cast it. e.g.
byte a = 1;
byte b = 2;
byte c = (byte) (a + b);
Not casting the operation will result in a compile error.
This is due to the following part of the Java Language Spec, §2.11.1:
A compiler encodes loads of literal values of types
byte
andshort
using Java Virtual Machine instructions that sign-extend those values to values of typeint
at compile-time or run-time. Loads of literal values of typesboolean
andchar
are encoded using instructions that zero-extend the literal to a value of typeint
at compile-time or run-time. [..]. Thus, most operations on values of actual typesboolean
,byte
,char
, andshort
are correctly performed by instructions operating on values of computational typeint
.
The reason behind this is also specified in that section:
Given the Java Virtual Machine's one-byte opcode size, encoding types into opcodes places pressure on the design of its instruction set. If each typed instruction supported all of the Java Virtual Machine's run-time data types, there would be more instructions than could be represented in a
byte
. [...] Separate instructions can be used to convert between unsupported and supported data types as necessary.
Enums always extend java.lang.Enum
, so it is impossible for an enum to extend a class. However, they can implement many interfaces.
Because of their specialized representation, there are more efficient maps and sets that can be used with enums as their keys. These will often run quicker than their non-specialized counterparts.
Using HttpUrlConnection on Android requires that you add the Internet permission to your app (in the AndroidManifest.xml
).
There are also other Java HTTP clients and libraries, such as Square's OkHttp, which are easier to use, and may offer better performance or more features.
Instead of using the javax.sound.sampled Clip
, you can also use the AudioClip
which is from the applet API. It is however recommended to use Clip
since AudioClip
is just older and presents limited functionalities.
Representation
Internally, a Java Date object is represented as a long; it is the number of milliseconds since a specific time (referred to as the epoch). The original Java Date class had methods for dealing with time zones, etc., but these were deprecated in favor of the then-new Calendar class.
So if all you want to do in your code is represent a specific time, you can create a Date class and store it, etc. If you want to print out a human-readable version of that date, however, you create a Calendar class and use its formatting to produce hours, minutes, seconds, days, time zones, etc. Keep in mind that a specific millisecond is displayed as different hours in different time zones; normally you want to display one in the "local" time zone, but the formatting methods have to take into account that you may want to display it for some other one.
Also be aware that the clocks used by JVMs do not usually have millisecond accuracy; the clock might only "tick" every 10 milliseconds, and therefore, if timing things, you cannot rely on measuring things accurately at that level.
Import Statement
import java.util.Date;
The Date
class may be imported from java.util
package.
Caution
Date
instances are mutable, so using them can make it difficult to write
thread-safe code or can accidentally provide write access to internal state. For example, in the below class, the getDate()
method allows the caller to modify the transaction date:
public final class Transaction {
private final Date date;
public Date getTransactionDate() {
return date;
}
}
The solution is to either return a copy of the date
field or use the new APIs in java.time
introduced in Java 8.
Most of the constructor methods in the Date
class have been deprecated and should not be used. In almost all cases, it is advisable to use Calendar
class for date operations.
Java 8
Java 8 introduces new time and date API in the package java.time
, including LocalDate and LocalTime. The classes in the java.time
package provide an overhauled API that is easier to use. If you are writing to Java 8 it is strongly encouraged that you use this new API. See Dates and Time (java.time.*) .
As of Java 8, Calendar
and its subclasses have been superseded by the java.time package and its subpackages. They should be preferred, unless a legacy API requires Calendar.
Nashorn is a JavaScript engine written in Java and included in Java 8. Everything you need is bundled in the javax.script
package.
Note that the ScriptEngineManager
provides a generic API allowing you to obtain script engines for various scripting languages (i.e. not only Nashorn, not only JavaScript).
Setting up JNI requires both a Java and a native compiler. Depending on the IDE and OS, there is some setting up required. A guide for Eclipse can be found here. A full tutorial can be found here.
These are the steps for setting up the Java-C++ linkage on windows:
.java
) into classes (.class
) using javac
..h
) files from the Java classes containing native
methods using javah
. These files "instruct" the native code which methods it is responsible for implementing.#include
) in the C++ source files (.cpp
) implementing the native
methods..dll
). This library contains the native code implementation.-Djava.library.path
) and load it in the Java source file (System.loadLibrary(...)
).Callbacks (Calling Java methods from native code) requires to specify a method descriptor. If the descriptor is incorrect, a runtime error occurs. Because of this, it is helpful to have the descriptors made for us, this can be done with javap -s
.
RMI requires 3 components: client, server and a shared remote interface. The shared remote interface defines the client-server contract by specifying the methods a server must implement. The interface must be visible to the server so that it can implement the methods; the interface must be visible to the client so that it knows which methods ("services") the server provides.
Any object implementing a remote interface is destined to take the role of a server. As such, a client-server relationship in which the server can also invoke methods in the client is in fact a server-server relationship. This is termed callback since the server can call back the "client". With this in mind, it is acceptable to use the designation client for the servers that function as such.
The shared remote interface is any interface extending Remote
. An object that functions as a server undergoes the following:
UnicastRemoteObject
which implements Remote
.UnicastRemoteObject
, or explicitly by being passed to UnicastRemoteObject#exportObject
.Registry
or indirectly through Naming
. This is only necessary for establishing initial communication since further stubs can be passed directly through RMI.In the project setup, the client and server projects are completely unrelated, but each specifies a shared project in its build path. The shared project contains the remote interfaces.
It is possible to iterate over an array using the for
-each loop, though java arrays do not implement Iterable; iterating is done by JVM using a non-accessible index in the background.
An operator is a symbol (or symbols) that tells a Java program to perform an operation on one, two or three operands. An operator and its operands form an expression (see the Expressions topic). The operands of an operator are themselves expressions.
This topic describes the 40 or so distinct operators defined by Java. The separate Expressions topic explains:
By default, assertions are disabled at runtime.
To enable assertions, you must run java with -ea
flag.
java -ea com.example.AssertionExample
Assertions are statements that will throw an error if their expression evaluates to false
. Assertions should only be used to test code; they should never be used in production.
The Scanner
class was introduced in Java 5. The reset()
method was added in Java 6, and a couple of new constructors were added in Java 7 for interoperability with the (then) new Path
interface.
A Properties object is a Map whose keys and values are Strings by convention. Although the methods of Map can be used to access the data, the more type-safe methods getProperty, setProperty, and stringPropertyNames are usually used instead.
Properties are frequently stored in Java property files, which are simple text files. Their format is documented thoroughly in the Properties.load method. In summary:
=
), or colon (:
) between the key and the value. The equals or colon may have any amount of whitespace before and after it, which is ignored.u
).\u
followed by four hexadecimal digits represents a UTF-16 character.Most frameworks, including Java SE’s own facilities like java.util.ResourceBundle, load property files as InputStreams. When loading a property file from an InputStream, that file is may only contain ISO 8859-1 characters (that is, characters in the 0–255 range). Any other characters must be represented as \u
escapes. However, you can write a text file in any encoding and use the native2ascii tool (which comes with every JDK) to do that escaping for you.
If you are loading a property file with your own code, it can be in any encoding, as long as you create a Reader (such as an InputStreamReader) based on the corresponding Charset. You can then load the file using load(Reader) instead of the legacy load(InputStream) method.
You can also store properties in a simple XML file, which allows the file itself to define the encoding. Such a file can be loaded with the loadFromXML method. The DTD describing the structure of such XML files is located at http://java.sun.com/dtd/properties.dtd .
Keep in mind that reflection might decrease performance, only use it when your task cannot be completed without reflection.
From the Java tutorial The Reflection API :
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
The Java Language Specification talks at length about the exact nature of constructor semantics. They can be found in JLS §8.8
This example focuses on parsing and creating JSON in Java using various libraries such as the Google Gson library, Jackson Object Mapper, and others..
Examples using other libraries could be found here: How to parse JSON in Java
Nothing is really random and thus the javadoc calls those numbers pseudorandom. Those numbers are created with a pseudorandom number generator.
When designing a recursive method keep in mind that you need:
Base Case. This will define when your recursion will stop and output the result. The base case in the factorial example is:
if (n <= 1) {
return 1;
}
Recursive Call. In this statement you re-call the method with a changed parameter. The recursive call in the factorial example above is:
else {
return n * factorial(n - 1);
}
In this example you compute the n-th factorial number. The first factorials are:
0! = 1
1! = 1
2! = 1 x 2 = 2
3! = 1 x 2 x 3 = 6
4! = 1 x 2 x 3 x 4 = 24
...
Current Java compilers (up to and including Java 9) do not perform tail-call elimination. This can impact the performance of recursive algorithms, and if the recursion is deep enough, it can lead to StackOverflowError
crashes; see Deep recursion is problematic in Java
Interfaces
are another way to achieve polymorphism in Java, apart from class based inheritance. Interfaces define a list of methods which form the API of the program. Classes must implement
an interface
by overriding all its methods.
Creating a new StringBuilder
with type char
as a parameter would result in calling the constructor with argument int capacity
and not the one with argument String string
:
StringBuilder v = new StringBuilder('I'); //'I' is a character, "I" is a String.
System.out.println(v.capacity()); --> output 73
System.out.println(v.toString()); --> output nothing
Unlike C/C++, Java is completely endian-neutral with respect to the underlying machine hardware. You do not get big or little endian behavior by default; you have to explicitly specify which behavior you want.
The byte
type is signed, with the range -128 to +127. To convert a byte value to its unsigned equivalent, mask it with 0xFF like this: (b & 0xFF)
.
It is much easier to start with marking a variable private
and expose it if necessary than to hide an already public
variable.
There is one exception where encapsulation may not be beneficial: "dumb" data structures (classes whose sole purpose is to hold variables).
public class DumbData {
public String name;
public int timeStamp;
public int value;
}
In this case, the interface of the class is the data that it holds.
Note that variables marked final
can be marked public
without violating encapsulation because they can't be changed after being set.
BigInteger
is immutable. Therefore you can't change its state. For example, the following won't work as sum
won't be updated due to immutability.
BigInteger sum = BigInteger.ZERO;
for(int i = 1; i < 5000; i++) {
sum.add(BigInteger.valueOf(i));
}
Assign the result to the sum
variable to make it work.
sum = sum.add(BigInteger.valueOf(i));
The official documentation of BigInteger
states that BigInteger
implementations should support all integers between -22147483647 and 22147483647 (exclusive). This means BigInteger
s can have more than 2 billion bits!
A “varargs” method argument allows callers of that method to specify multiple arguments of the designated type, each as a separate argument. It is specified in the method declaration by three ASCII periods (...
) after the base type.
The method itself receives those arguments as a single array, whose element type is the type of the varargs argument. The array is created automatically (though callers are still permitted to pass an explicit array instead of passing multiple values as separate method arguments).
Rules for varargs:
You must follow above rules otherwise program will give compile error.
Best used for objects which depend on internals during invoking a call, but are stateless otherwise, like SimpleDateFormat
, Marshaller
For Random
ThreadLocal usage, consider using ThreadLocalRandom
A resource is file-like data with a path-like name, which resides in the classpath. The most common use of resources is bundling application images, sounds, and read-only data (such as default configuration).
Resources can be accessed with the ClassLoader.getResource and ClassLoader.getResourceAsStream methods. The most common use case is to have resources placed in the same package as the class which reads them; the Class.getResource and Class.getResourceAsStream methods serve this common use case.
The only difference between a getResource method and getResourceAsStream method is that the former returns a URL, while the latter opens that URL and returns an InputStream.
The methods of ClassLoader accept a path-like resource name as an argument and search each location in the ClassLoader’s classpath for an entry matching that name.
The resource name is similar to the path portion of a relative URL. On all platforms, it uses forward slashes (/
) as directory separators. It must not start with a slash.
The corresponding methods of Class are similar, except:
For instance:
package com.example;
public class ExampleApplication {
public void readImage()
throws IOException {
URL imageURL = ExampleApplication.class.getResource("icon.png");
// The above statement is identical to:
// ClassLoader loader = ExampleApplication.class.getClassLoader();
// URL imageURL = loader.getResource("com/example/icon.png");
Image image = ImageIO.read(imageURL);
}
}
Resources should be placed in named packages, rather than in the root of a .jar file, for the same reason classes are placed in packages: To prevent collisions among multiple vendors. For example, if multiple .jar files are in the classpath, and more than one of them contains a config.properties
entry in its root, calls to the getResource or getResourceAsStream methods will return the config.properties from whichever .jar is listed first in the classpath. This is not predictable behavior in environments where the classpath order is not under the direct control of the application, such as Java EE.
All getResource and getResourceAsStream methods return null
if the specified resource does not exist. Since resources must be added to the application at build time, their locations should be known when the code is being written; a failure to find a resource at runtime is usually the result of programmer error.
Resources are read-only. There is no way to write to a resource. Novice developers often make the mistake of assuming that since the resource is a separate physical file when developing in an IDE (like Eclipse), it will be safe to treat it like a separate physical file in the general case. However, this is not correct; applications are almost always distributed as archives such as .jar or .war files, and in such cases, a resource will not be a separate file and will not be writable. (The getFile method of the URL class is not a workaround for this; despite its name, it merely returns the path portion of a URL, which is by no means guaranteed to be a valid filename.)
There is no safe way to list resources at runtime. Again, since the developers are responsible for adding resource files to the application at build time, developers should already know their paths. While there are workarounds, they are not reliable and will eventually fail.
It is strongly recommended that you use these options only:
Information gathered from official Java documentation.
The examples above strictly follow the new official style guide from Oracle. They are in other words not subjectively made up by the authors of this page.
The official style guide has been carefully written to be backward compatible with the original style guide and the majority of code out in the wild.
The official style guide has been peer reviewed by among others, Brian Goetz (Java Language Architect) and Mark Reinhold (Chief Architect of the Java Platform).
The examples are non-normative; While they intend to illustrate correct way of formatting the code, there may be other ways to correctly format the code. This is a general principle: There may be several ways to format the code, all adhering to the official guidelines.
In Java, objects are allocated in the heap, and heap memory is reclaimed by automatic garbage collection. An application program cannot explicitly delete a Java object.
The basic principles of Java garbage collection are described in the Garbage collection example. Other examples describe finalization, how to trigger the garbage collector by hand, and the problem of storage leaks.
Immutable objects have fixed state (no setters), so all state must be known at object creation time.
Although not technically required, it is best practice to make all fields final
. This will make the immutable class thread-safe (cf. Java Concurrency in Practice, 3.4.1).
The examples show several patterns that can assist with achieving this.
Cloning can be tricky, especially when the object's fields hold other objects. There are situations where you want to perform a deep copy, instead of only copying the field values (i.e. references to the other objects).
The bottom line is clone is broken, and you should think twice before implementing the Cloneable
interface and overriding the clone
method. The clone
method is declared in the Object
class and not in the Cloneable
interface, so Cloneable
fails to function as an interface because it lacks a public clone
method. The result is the contract for using clone
is thinly documented and weakly enforced. For example, a class that overrides clone
sometimes relies on all its parent classes also overriding clone
. They are not enforced to do so, and if they do not your code may throw exceptions.
A much better solution for providing cloning functionality is to provide a copy constructor or copy factory. Refer to Joshua Bloch's Effective Java Item 11: Override clone judiciously.
This topic about Java collections from guava, apache, eclipse: Multiset, Bag, Multimap, utils function from this lib and so on.
A list is an object which stores a an ordered collection of values. "Ordered" means the values are stored in a particular order--one item comes first, one comes second, and so on. The individual values are commonly called "elements". Java lists typically provide these features:
Adding a value to a list at some point other than the end will move all of the following elements "down" or "to the right". In other words, adding an element at index n moves the element which used to be at index n to index n+1, and so on. For example:
List<String> list = new ArrayList<>();
list.add("world");
System.out.println(list.indexOf("world")); // Prints "0"
// Inserting a new value at index 0 moves "world" to index 1
list.add(0, "Hello");
System.out.println(list.indexOf("world")); // Prints "1"
System.out.println(list.indexOf("Hello")); // Prints "0"
BufferedWriter
(using BufferedWriter.write()
) after closing the BufferedWriter
(using BufferedWriter.close()
), it will throw an IOException
.BufferedWriter(Writer)
constructor does NOT throw an IOException
. However, the FileWriter(File)
constructor throws a FileNotFoundException
, which extends IOException
. So catching IOException
will also catch FileNotFoundException
, there is never a need for a second catch statement unless you plan on doing something different with the FileNotFoundException
.As class name denotes, LocalTime
represents a time without a time-zone. It doesn't represent a date. It's a simple label for a given time.
The class is value-based and the equals
method should be used when doing comparisons.
This class is from the package java.time.
When implementing a compareTo(..)
method which depends upon a double
, do not do the following:
public int comareTo(MyClass other) {
return (int)(doubleField - other.doubleField); //THIS IS BAD
}
The truncation caused by the (int)
cast will cause the method to sometimes incorrectly return 0
instead of a positive or negative number, and can thus lead to comparison and sorting bugs.
Instead, the simplest correct implementation is to use Double.compare, as such:
public int comareTo(MyClass other) {
return Double.compare(doubleField,other.doubleField); //THIS IS GOOD
}
A non-generic version of Comparable<T>
, simply Comparable
, has existed since Java 1.2. Other than for interfacing with legacy code, it's always better to implement the generic version Comparable<T>
, as it doesn't require casting upon comparison.
It is very standard for a class to be comparable to itself, as in:
public class A implements Comparable<A>
While it is possible to break from this paradigm, be cautious when doing so.
A Comparator<T>
can still be used on instances of a class if that class implements Comparable<T>
. In this case, the Comparator
's logic will be used; the natural ordering specified by the Comparable
implementation will be ignored.
The Java Language Specification (JLS) classifies the different kinds of Java class as follows:
A top level class is a class that is not a nested class.
A nested class is any class whose declaration occurs within the body of another class or interface.
An inner class is a nested class that is not explicitly or implicitly declared static.
An inner class may be a non-static member class, a local class, or an anonymous class. A member class of an interface is implicitly static so is never considered to be an inner class.
In practice programmers refer to a top level class that contains an inner class as the "outer class". Also, there is a tendency to use "nested class" to refer to only to (explicitly or implicitly) static nested classes.
Note that there is a close relationship between anonymous inner classes and the lambdas, but lambdas are classes.
Top level classes are the "base case". They are visible to other parts of a program subject to normal visibility rules based on access modifier semantics. If non-abstract, they can be instantiated by any code that where the relevant constructors are visible based on the access modifiers.
Static nested classes follow the same access and instantiation rules as top level classes, with two exceptions:
private
, which makes it inaccessible outside of its enclosing top level class.private
members of the enclosing top-level class and all of its tested class.This makes static nested classes useful when you need to represent multiple "entity types" within a tight abstraction boundary; e.g. when the nested classes are used to hide "implementation details".
Inner classes add the ability to access non-static variables declared in enclosing scopes:
final
. (For Java 8 and later, they can be effectively final.)The fact that an inner class instance can refer to variables in a enclosing class instance has implications for instantiation. Specifically, an enclosing instance must be provided, either implicitly or explicitly, when an instance of an inner class is created.
Java class loading
The JVM (Java Virtual Machine) will load classes as and when the classes are required (this is called lazy-loading). Locations of the classes to be used are specified in three places:-
jre/lib/ext/
)Classes are loaded using classes that are subtypes of java.lang.ClassLoader
. This described in a more detail in this Topic: Classloaders.
Classpath
The classpath is a parameter used by the JVM or compiler which specifies the locations of user-defined classes and packages.
This can be set in the command line as with most of these examples or through an environmental variable (CLASSPATH
)
XML Parsing is the interpretation of XML documents in order to manipulate their content using sensible constructs, be they "nodes", "attributes", "documents", "namespaces", or events related to these constructs.
Java has a native API for XML document handling, called JAXP, or Java API for XML Processing. JAXP and a reference implementation has been bundled with every Java release since Java 1.4 (JAXP v1.1) and has evolved since. Java 8 shipped with JAXP version 1.6.
The API provides different ways of interacting with XML documents, which are :
The DOM interface aims to provide a W3C DOM compliant way of interpreting XML. Various versions of JAXP have supported various DOM Levels of specification (up to level 3).
Under the Document Object Model interface, an XML document is represented as a tree, starting with the "Document Element". The base type of the API is the Node
type, it allows to navigate from a Node
to its parent, its children, or its siblings (although, not all Node
s can have children, for example, Text
nodes are final in the tree, and never have childre). XML tags are represented as Element
s, which notably extend the Node
with attribute-related methods.
The DOM interface is very usefull since it allows a "one line" parsing of XML documents as trees, and allows easy modification of the constructed tree (node addition, suppression, copying, ...), and finally its serialization (back to disk) post modifications. This comes at a price, though : the tree resides in memory, therefore, DOM trees are not always practical for huge XML documents. Furthermore, the construction of the tree is not always the fastest way of dealing with XML content, especially if one is not interested in all parts of the XML document.
The SAX API is an event-oriented API to deal with XML documents. Under this model, the components of an XML documents are interpreted as events (e.g. "a tag has been opened", "a tag has been closed", "a text node has been encountered", "a comment has been encountered")...
The SAX API uses a "push parsing" approach, where a SAX Parser
is responsible for interpreting the XML document, and invokes methods on a delegate (a ContentHandler
) to deal with whatever event is found in the XML document. Usually, one never writes a parser, but one provides a handler to gather all needed informations from the XML document.
The SAX interface overcomes the DOM interface's limitations by keeping only the minimum necessary data at the parser level (e.g. namespaces contexts, validation state), therefore, only informations that are kept by the ContentHandler
- for which you, the developer, is responsible - are held into memory. The tradeoff is that there is no way of "going back in time/the XML document" with such an approach : while DOM allows a Node
to go back to its parent, there is no such possibility in SAX.
The StAX API takes a similar approach to processing XML as the SAX API (that is, event driven), the only very significative difference being that StAX is a pull parser (where SAX was a push parser). In SAX, the Parser
is in control, and uses callbacks on the ContentHandler
. In Stax, you call the parser, and control when/if you want to obtain the next XML "event".
The API starts with XMLStreamReader (or XMLEventReader), which are the gateways through which the developer can ask nextEvent()
, in an iterator-style way.
Java comes with a powerful and flexible mechanism for localizing your applications, but it's also easy to misuse and wind up with a program that disregards or mangles the user's locale, and therefore how they expect your program to behave.
Your users will expect to see data localized to the formats they're used to, and attempting to support this manually is a fools errand. Here is just a small example of the different ways users expect to see content you might assume is "always" displayed a certain way:
Dates | Numbers | Local Currency | Foreign Currency | Distances | |
---|---|---|---|---|---|
Brazil | |||||
China | |||||
Egypt | |||||
Mexico | 20/3/16 | 1.234,56 | $1,000.50 | 1,000.50 USD | |
UK | 20/3/16 | 1,234.56 | £1,000.50 | 100 km | |
USA | 3/20/16 | 1,234.56 | $1,000.50 | 1,000.50 MXN | 60 mi |
Locale
XPath expressions are used to navigate and select one or more nodes within an XML tree document, such as selecting a certain element or attribute node.
See this W3C recommendation for a reference on this language.
The javac
command is used for compiling Java source files to bytecode files. Bytecode files are platform independent. This means that you can compile your code on one kind of hardware and operating system, and then run the code on any other platform that supports Java.
The javac
command is included in the Java Development Kit (JDK) distributions.
The Java compiler and the rest of the standard Java toolchain places the following restrictions on the code:
Note: The javac
compiler should not be confused with the Just in Time (JIT) compiler which compiles bytecodes to native code.
The XJC tool is available as part of the JDK. It allows creating java code annotated with JAXB annotations suitable for (un)marshalling.
Notice that the API recommends that, as of version 1.5, the preferred way to create a Process is using ProcessBuilder.start()
.
Another important remark is that the exit value produced by waitFor
is dependent from the program/script being executed. For instance, the exit codes produced by calc.exe are different from notepad.exe.
When a regular Java application is launched using the java
command (or equivalent), a main
method will be called, passing the arguments from the command line in the args
array.
Unfortunately, the Java SE class libraries do not provide any direct support for command argument processing. This leaves you two alternatives:
This Topic will attempt to cover some of the more popular 3rd-party libraries. For an extensive list of the alternatives, see this answer to the StackOverflow Question "How to parse command line arguments in Java?".
Goals
The primary goal of a Fluent Interface is increased readability.
When used for constructing objects, the choices available to the caller can be made clearly and enforced via compile-time checks. For example, consider the following tree of options representing steps along the path to construct some complex object:
A -> B
-> C -> D -> Done
-> E -> Done
-> F -> Done.
-> G -> H -> I -> Done.
A builder using a fluent interface would allow the caller to easily see what options are available at each step. For example, A -> B is possible, but A -> C is not and would result in a compile-time error.
The Symantec JIT compiler was available in the Sun Java from 1.1.5 onwards, but it had problems.
The Hotspot JIT compiler was added to Sun Java in 1.2.2 as a plugin. In Java 1.3, JIT was enabled by default.
(Source: When did Java get a JIT compiler?
The use of modules is encouraged but not required, this allows existing code to continue working in Java 9. It also allows for a gradual transition to modular code.
Any non-modular code is put in an unnamed module when it is compiled. This is a special module that is able to use types from all other modules but only from packages which have an exports
declaration.
All packages in the unnamed module are exported automatically.
Keywords, e.g. module
etc..., are restricted in use within the module declaration but can be continue to be used as identifiers elsewhere.
This topic is about specific aspects of the Java language syntax that are either error prone or that that should not be used in certain ways.
ServiceLoader
can be used to get instances of classes extending a given type(=service) that are specified in a file packed in a .jar
file. The service that is extended/implemented is often a interface, but this is not required.
The extending/implementing classes need to provide a zero argument constructor for the ServiceLoader
to instantiate them.
To be discovered by the ServiceLoader
a text file with the name of the fully qualified type name of the implemented service needs to be stored inside the META-INF/services
directory in the jar file. This file contains one fully qualified name of a class implementing the service per line.
A classloader is a class whose primary purpose is to mediate the location and loading of classes used by an application. A class loader can also find and loaded resources.
The standard classloader classes can load classes and resources from directories in the file system and from JAR and ZIP files. They can also download and cache JAR and ZIP files from a remote server.
Classloaders are normally chained, so that the JVM will try to load classes from the standard class libraries in preference to application-provided sources. Custom classloaders allow the programmer to alter this. The also can do such things as decrypting bytecode files and bytecode modification.
This should help you understand a "Null Pointer Exception" -- one gets one of those because an object reference is null, but the program code expects the program to use something in that object reference. However, that deserves its own topic...
This topic describes some "micro" Java coding practices that are inefficient. In most cases, the inefficiencies are relatively small, but it is still worth avoiding them is possible.
BufferedImage.getGraphics()
always returns Graphics2D
.
Using a VolatileImage
may significantly improve the speed of drawing operations, but also has its drawbacks: its contents may be lost at any moment and they may have to be redrawn from scratch.
An applet is a Java application that normally runs inside a web browser. The basic idea is to interact with the user without the need to interact with the server and transfer information. This concept was very successful around the year 2000 when internet communication was slow and expensive.
An applet offers five methods to control their life cycle.
method name | description |
---|---|
init() | is called once when the applet is loaded |
destroy() | is called once when the applet gets removed from memory |
start() | is called whenever the applet gets visible |
stop() | is called whenever the applet get overlapped by other windows |
paint() | is called when needed or manually triggered by calling repaint() |
SelectionKey
defines the different selectable operations and information between its Selector and Channel. In particular, the attachment can be used to store connection-related information.
Handling OP_READ
is pretty straight-forward. However, care should be taken when dealing with OP_WRITE
: most of the time, data can be written to sockets so the event will keep firing. Make sure to register OP_WRITE
only before you want to write data (see that answer).
Also, OP_CONNECT
should be cancelled once the Channel has connected (because, well, it is connected. See this and that answers on SO). Hence the OP_CONNECT
removal after finishConnect()
succeeded.
The goal here is to not lose content, so the regex must not consume (match) any input. Rather it must match between the last character of the previous target input and the first character of the next target input. eg for 8-character substrings, we need to break the input up (ie match) at the places marked below:
a b c d e f g h i j k l m n o p q r s t u v w x y z
^ ^ ^
Ignore the spaces in the input which were required to show between character positions.
The value null
is the default value for an uninitialized value of a field whose type is a reference type.
NullPointerException
(or NPE) is the exception that is thrown when you attempt to perform an inappropriate operation on the null
object reference. Such operations include:
null
target object,null
target object,null
array object or access its length,null
object reference as the mutex in a synchronized
block,null
object reference,null
object reference, andnull
object reference.The most common root causes for NPEs:
null
in certain circumstances.Examples of commonly used methods that return null
include:
get(key)
method in the Map
API will return a null
if you call it with a key that doesn't have a mapping.getResource(path)
and getResourceAsStream(path)
methods in the ClassLoader
and Class
APIs will return null
if the resource cannot be found.get()
method in the Reference
API will return null
if the garbage collector has cleared the reference.getXxxx
methods in the Java EE servlet APIs will return null
if you attempt fetch a non-existent request parameter, session or session attribute and so on.There are strategies for avoiding unwanted NPEs, such as explicitly testing for null
or using "Yoda Notation", but these strategies often have the undesirable result of hiding problems in your code that really ought to be fixed.
The java
command is used for running a Java application from the command line. It is available as a part of any Java SE JRE or JDK.
On Windows systems there are two variants of the java
command:
java
variant launches the application in a new console window.javaw
variant launches the application without creating a new console window.On other systems (e.g. Linux, Mac OSX, UNIX) only the java
command is provided, and it does not launch a new console window.
The <opt>
symbol in the syntax denotes an option on the java
command line. The "Java Options" and "Heap and stack sizing options" topics cover the most commonly used options. Others are covered in the JVM Flags topic.
Many on essentially combinations of volatile reads or writes and CAS operations. Best way to understand this is to look at the source code directly. E.g. AtomicInteger, Unsafe.getAndSet
The Unsafe
class allows a program to do things that are not allowed by the Java compiler. Normal programs should avoid using Unsafe
.
WARNINGS
If you make a mistake using the Unsafe
APIs, your applications are liable to cause the JVM to crash and/or exhibit symptoms that are hard to diagnose.
The Unsafe
API is subject to change without notice. If you use it in your code, you may need to rewrite the code when changing Java versions.
The Java Memory Model is the section of the JLS that specifies the conditions under which one thread is guaranteed to see the effects of memory writes made by another thread. The relevant section in recent editions is "JLS 17.4 Memory Model" (in Java 8, Java 7, Java 6)
There was a major overhaul of the Java Memory Model in Java 5 which (among other things) changed the way that volatile
worked. Since then, the memory model been essentially unchanged.
At the most fundamental level, a Java program can be deployed by copying a compiled class (i.e. a ".class" file) or a directory tree containing compiled classes. However Java is normally deployed in one of the following ways:
By copying a JAR file or collection of JAR files to the system where they will be executed; e.g. using javac
.
By copying or uploading a WAR, EAR or similar file to a "servlet container" or "application server".
By running some kind of application installer that automates the above. The installer might also install an embedded JRE.
By putting the JAR files for the application onto a web server to allow them to be launched using Java WebStart.
The Creating JAR, WAR and EAR files example summarizes the different ways to create these files.
There are numerous open source and commercial "installer generator" and "EXE generator" tools for Java. Similarly, there are tools for obfuscating Java class files (to make reverse engineering harder) and for adding runtime license checking. These are all out of scope for the "Java Programming Language" documentation.
If you use an IDE and/or build system, it is much easier to set up this kind of project. You create a main application module, then API module, then create a plugin module and make it dependent on the API module or both. Next, you configure where the project artifacts are to be put - in our case the compiled plugin jars can be sent straight to 'plugins' directory, thus avoiding doing manual movement.
There are numerous frameworks available for unit testing within Java. The most popular option by far is JUnit. It is documented under the following:
JUnit4 - Proposed tag for JUnit4 features; not yet implemented.
Other unit test frameworks do exist, and have documentation available:
There are several other tools used for unit testing:
Mockito - Mocking framework; allows objects to be mimicked. Useful for mimicking the expected behavior of an external unit within a given unit's test, as to not link the external unit's behavior to the given unit's tests.
JBehave - BDD Framework. Allows tests to be linked to user behaviors (allowing requirement/scenario validation). No documents tag available at time of writing; here is an external link.
In order for a class to be a Java Bean must follow this standard - in summary:
java.io.Serializable
interface.For a reference on the operators that can be used in expressions, see Operators.
Reference: Enhancements in Java SE 8
Packages provide access protection.
package statement must be first line of source code. There can only be one package in one source file.
With help of packages conflict between different modules can be avoided.
While examples should be clearly made, some topics that must be covered are:
JShell requires the Java 9 JDK, which can currently (March 2017) be downloaded as early access snapshots from jdk9.java.net. If, when you try to run the jshell
command, you get an error beginning with Unable to locate an executable
, make sure JAVA_HOME
is set correctly.
The following packages are imported automatically when JShell starts:
import java.io.*
import java.math.*
import java.net.*
import java.nio.file.*
import java.util.*
import java.util.concurrent.*
import java.util.function.*
import java.util.prefs.*
import java.util.regex.*
import java.util.stream.*
There are two types of Internet Protocol Traffic -
1. TCP - Transmission Control Protocol
2. UDP - User Datagram Protocol
TCP is a connection-oriented protocol.
UDP is a connectionless protocol.
TCP is suited for applications that require high reliability, and transmission time is relatively less critical.
UDP is suitable for applications that need fast, efficient transmission, such as games. UDP's stateless nature is also useful for servers that answer small queries from huge numbers of clients.
In simpler words -
Use TCP when you cannot afford to loose data and when time to send and receive data doesn't matter.
Use UDP when you cannot afford to loose time and when loss of data doesn't matter.
There is an absolute guarantee that the data transferred remains intact and arrives in the same order in which it was sent in case of TCP.
whereas there is no guarantee that the messages or packets sent would reach at all in UDP.
The Java Scripting API enables external scripts to interact with Java
The Scripting API can enable interaction between the script and java. The Scripting Languages must have an implementation of Script Engine on the classpath.
By Default JavaScript (also known as ECMAScript) is provided by nashorn by default. Every Script Engine has a script context where all the variables, functions, methods are stored in bindings. Sometimes you might want to use multiple contexts as they support redirecting the output to a buffered Writer and error to another.
There are many other script engine libraries like Jython and JRuby. As long as they are on the classpath you can eval code.
We can use bindings to expose variables into the script. We need multiple bindings in some cases as exposing variables to the engine basically is exposing variables to only that engine, sometimes we require to expose certain variables like system environment and path that is the same for all engines of the same type. In that case, we require a binding which is a global scope. Exposing variables to that expose it to all script engines created by the same EngineFactory
Generics can be used with Deque.
Deque<Object> deque = new LinkedList<Object>();
When a deque is used as a queue, FIFO (First-In-First-Out) behavior results.
Deques can also be used as LIFO (Last-In-First-Out) stacks.
For more information about methods, go through this Documentation.
Some immutable classes in Java:
Nested Class[ref] (needs a reference to enclosing class)
class Outer {
class Inner {
public:
Inner(Outer* o) :outer(o) {}
private:
Outer* outer;
};
};
[non-static] Nested Class (aka Inner Class or Member Class)
class OuterClass {
...
class InnerClass {
...
}
}
Static Nested Class
class Outer {
class Inner {
...
};
};
Static Nested Class (aka Static Member Class)[ref]
class OuterClass {
...
static class StaticNestedClass {
...
}
}
(e.g. event handling)
Local Class[ref]
void fun() {
class Test {
/* members of Test class */
};
}
See also Lambda expressions
Local Class[ref]
class Test {
void f() {
new Thread(new Runnable() {
public void run() {
doSomethingBackgroundish();
}
}).start();
}
}
The following Overriding vs Overloading points apply to both C++ and Java:
Polymorphism is the ability for objects of different classes related by inheritance to respond differently to the same method call. Here's an example:
In C++, polymorphism is enabled by virtual methods. In Java, methods are virtual by default.
In C++, it's a good idea to declare a destructor as virtual to ensure that the subclass' destructor will be called if the base-class pointer is deleted.
In Java, a finalize method is similar a destructor in C++; however, finalizers are unpredictable (they rely on GC). Best practice - use a "close" method to explicitly cleanup.
protected void close() {
try {
// do subclass cleanup
}
finally {
isClosed = true;
super.close();
}
}
protected void finalize() {
try {
if(!isClosed) close();
}
finally {
super.finalize();
}
}
Concept | C++ | Java |
---|---|---|
Abstract Method declared without an implementation | pure virtual methodvirtual void eat(void) = 0; | abstract methodabstract void draw(); |
Abstract Class cannot be instantiated | cannot be instantiated; has at least 1 pure virtual methodclass AB {public: virtual void f() = 0;}; | cannot be instantiated; can have non-abstract methodsabstract class GraphicObject {} |
Interface no instance fields | no "interface" keyword, but can mimic a Java interface with facilities of an abstract class | very similar to abstract class, but 1) supports multiple inheritance; 2) no instance fieldsinterface TestInterface {} |
Modifier | C++ | Java |
---|---|---|
Public - accessible by all | no special notes | no special notes |
Protected - accessible by subclasses | also accessible by friends | also accessible within same package |
Private - accessible by members | also accessible by friends | no special notes |
default | class default is private; struct default is public | accessible by all classes within the same package |
other | Friend - a way to grant access to private & protected members without inheritance (see below) |
class Node {
private:
int key; Node *next;
// LinkedList::search() can access "key" & "next"
friend int LinkedList::search();
};
The diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C? (from Wikipedia)
While C++ has always been susceptible to the diamond problem, Java was susceptible until Java 8. Originally, Java didn't support multiple inheritance, but with the advent of default interface methods, Java classes can not inherit "implementation" from more than one class.
In Java all classes inherit, either implicitly or explicitly, from the Object class. Any Java reference can be cast to the Object type.
C++ doesn't have a comparable "Object" class.
Java Collections are symonymous with C++ Containers.
Bits | Min | Max | C++ Type (on LLP64 or LP64) | Java Type |
---|---|---|---|---|
8 | -2(8-1) = -128 | 2(8-1)-1 = 127 | char | byte |
8 | 0 | 2(8)-1 = 255 | unsigned char | -- |
16 | -2(16-1) = -32,768 | 2(16-1)-1 = 32,767 | short | short |
16 | 0 (\u0000) | 2(16)-1 = 65,535 (\uFFFF) | unsigned short | char (unsigned) |
32 | -2(32-1) = -2.147 billion | 2(32-1)-1 = 2.147 billion | int | int |
32 | 0 | 2(32)-1 = 4.295 billion | unsigned int | -- |
64 | -2(64-1) | 2(16-1)-1 | long* | long long |
64 | 0 | 2(16)-1 | unsigned long* unsigned long long | -- |
*
Win64 API is only 32 bit