We use the Reflection API to find out about the internals of a Java class — its fields, constructors, methods and annotations. We can also use it to programmatically instantiate objects, invoke methods and access fields at runtime.
This is a very powerful API. It is used extensively by JEE containers, the Spring framework, GUI builders and other APIs.
In my previous post about the compiler
-g debug flag, I mentioned the concept of decompiling Java code. Java decompilers are very useful if you need to retrieve lost source code, or you want to see what code the compiler has automatically generated for you (e.g. for auto-boxing, generics, enums, enhanced for-loops and the like).
Occasionally you might have to debug your Java code. Now maybe your code is always correct, and never needs debugging, but then you might want to help someone else in the team who has a problem.
When we debug code, we want to have as much information about our code as possible. One of the problems we face when debugging is that the compiler strips the method parameter names and local variable names from the class file. If we’re stepping through our code, we would like to see the correct names in our debugger.
There’s probably nothing programmers hate more than documenting their code. Even doing timesheets takes second place on the list of things programmers hate to do.
Fortunately help is at hand.
Here’s a fact that you may not know. When you auto-box integral primitives (
long) to their respective wrapper classes (
Long), the wrapper classes cache all values from
+127. These values are later used by the
valueOf() methods to give better performance than using a constructor.
Occasionally during development, your program may crash with an
OutOfMemoryError. What happened and how do you prevent it?
You may have seen the
@SuppressWarnings annotation before. Have you wondered how and why to use it?
This is a term you may not have heard. Although the term isn’t used often, these kinds of functions are common. We use higher-order functions all the time when we use streams.
Last week I wrote about functional interfaces and how to use them as targets for lambda expressions. I showed you how we create a variable of a functional interface type and assign a lambda expression to it. Today I want to help you make sense of the set of standard functional interfaces.
You’ve probably heard of a functional interface before, often in the same breath as lambdas. What are functional interfaces, and why are they used with lambdas?
Lambdas and functional interfaces go hand in hand in Java.
A functional interface is simply an interface that has a single abstract method. Before Java 8, they were referred to as SAM interfaces.
Why are these interfaces so important that they have their own term? Two reasons: