Learning the basics of Java is easy. But really delving into the language and studying its more advanced concepts and nuances is what will make you a great Java developer. The web is abundant with “soft”, “cheap”, “low end” Java tutorials, but what it is missing is material to really take you to the next level.
This course is designed to help you make the most effective use of Java. It discusses advanced topics, including object creation, concurrency, serialization, reflection and many more. It will guide you through your journey to Java mastery!
About the Author
Andriy has completed his Master Degree in Computer Science at Zhitomir Institute of Engineering and Technologies, Ukraine. For the last 15 years he has been working as the Consultant/Software Developer/Senior Software Developer/Team Lead for many successful projects.
Andriy has great experience in enterprise architecture, web development, software development practices and software platforms, object-oriented analysis and design, development of rich user interfaces, relational database management systems, NoSQL solutions and operating systems.
In this lesson, we will discuss the creation of new class instances (objects). We will see how constructors are used as well as more advanced creation techniques, such as static initialization, construction patterns and more. Additionally, more topics will be introduced, such as the use of initialization blocks, finalizers and how the Garbage Collector gets involved in the process.
In this lesson, we are going to see how to use methods common to all objects. Methods common to all objects are inherited by the parent Object class. These include the equals and hashCode methods, as well as the toString and equals methods. Additionally, we will discuss the equals and == operator and some helpful helper classes of the new Java 7 Objects class that can be used to do the heavy lifting of our functionality.
In this lesson we will delve into the foundational building blocks which the Java language provides and introduce a couple of design principles, aiming to help you to make better design decisions. We are going to discuss interfaces and interfaces with default methods (new feature of Java 8), abstract and final classes, immutable classes, inheritance, composition and revisit a bit the visibility (or accessibility) rules we have briefly touched.
In this lesson we will discuss Generics. The idea of generics represents the abstraction over types (well-known to C++ developers as templates). It is a very powerful concept that allows to develop abstract algorithms and data structures and to provide concrete types to operate on later. Generics revolutionized the way Java programs are being written, delivering much stronger type guaranties and making code significantly safer. In this section we are going to cover the usage of generics everywhere, starting from interfaces, classes and methods. Providing a lot of benefits, generics however do introduce some limitations and side-effects which we also are going to cover.
In this lesson we will discuss enums (or enumerations) and annotations. The idea of enums is simple, but quite handy: it represents a fixed, constant set of values. What it means in practice is that enums are often used to design the concepts which have a constant set of possible states. From the other side, annotations are a special kind of metadata which could be associated with different elements and constructs of the Java language. Interestingly, annotations have contributed a lot into the elimination of boilerplate XML descriptors used in Java ecosystem mostly everywhere. They introduced the new, type-safe and robust way of configuration and customization techniques.
In this lesson we will spend some time discussing different aspects related to designing and implementing methods in Java. It is very easy to write methods in Java, however there are many things which could make your methods more readable and efficient. We will discuss the various details of method design, like the method body and signature, techniques like method overloading and overriding, optimizations like Inlining and Immutability, and other miscellaneous items, like documentation.
In this lesson we are going to continue discussing general principles of good programming style and robust design in Java. We will discuss Variable scopes, Class fields and local variables, Method arguments and local variables, Boxing and unboxing, Interfaces, Strings, Naming conventions, Standard Libraries, Immutability, Testing and more!
In this lesson we are going to continue discussing how and when to use Exceptions. Exceptions in Java are an important instrument to signal abnormal (or exceptional) conditions in the program flow which may prevent it to make a further progress. We will discuss Checked and unchecked exceptions, using try-with-resources, exceptions in conjunction with lambdas, standard Java exceptions, how to define our own exceptions, documenting exceptions and logging them!
In this lesson we are going to look at what Java can offer to the developers in order to help them to write robust and safe applications in concurrent world. In order to utilize the full power of available computational units, the applications should be ready to support multiple execution flows which are running concurrently and competing for resources and memory. We will discuss Threads and Thread Groups, Concurrency, Synchronization and Immutability, Futures, Executors and Thread Pools, Atomic Operations and many more!
In this lesson we are going to look at serialization: the process of translating Java objects into a format that can be used to store and be reconstructed later in the same (or another) environment. Serialization not only allows saving and loading Java objects to/from the persistent storage, but is also a very important component of modern distributed systems communication. We will discuss the Serializable and Externalizable interfaces, JAXB and JSON-P, perils of serialization and we will look beyond the Java standard library and specifications!
In this lesson we are going to look at a very interesting subject called reflection. Reflection is the ability of the program to examine or introspect itself at runtime. Reflection is an extremely useful and powerful feature which significantly expands the capabilities of the program to perform its own inspections, modifications or transformations during its execution, without a single line of code change. We will discuss the Reflection API, how to access generic type parameters, method handles and method argument names, and some of the pitfalls of reflection!
In this lesson we are going to take 10000 feet view of the Java Compiler API. This API provides programmatic access to the Java compiler itself and allows developers to compile Java classes from source files on the fly from application code. We also are going to walk through the Java Compiler Tree API, which provides access to Java syntax parser functionality. By using this API, Java developers have the ability to directly plug into syntax parsing phase and post-analyze Java source code being compiled.
In this lesson we are going to demystify the magic of annotation processing, which is often used to inspect, modify or generate source code, driven only by annotations. Essentially, annotation processors are some kind of plugins of the Java compiler. Annotation processors used wisely could significantly simplify the life of Java developers so that is why they are often bundled with many popular libraries and frameworks. Annotations processors are typically used to inspect the codebase against the presence of particular annotations and, depending on use case, to: generate a set of source or resource files, mutate (modify) the existing source code or analyze the exiting source code and generate diagnostic messages.
In this final lesson we are going to talk about Java agents, a real black magic for regular Java developers out there. Java agents are able to “intrude” into the execution of Java applications running on the JVM at runtime by performing the direct modifications of the bytecode. Java agents are extremely as powerful as dangerous: they can do mostly everything however if something goes wrong, they can easily crash the JVM.
Make sure to retweet this, let your social followers know!
— Java Code Geeks (@javacodegeeks) October 16, 2015