I ran into this block of code today, and I don't know how it works. I know how to make anonymous classes, but I'm used to seeing a method signature and not just a pair of braces. Is the code between those braces put into a static block? Does it go into the constructor? Or is it something else altogether?
conext.checking(new Expectations() {
{ // <- what does this pair of braces do?
oneOf(alarm).getAttackAlarm(null);
}
});
It's an instance initializer that calls the code within the context of the created object.
This is equivalent to
Expectations exp = new Expectations();
exp.oneOf(alarm).getAttackAlarm(null);
conext.checking(exp)
Whoever wrote it might have thought he was being more efficient by not declaring a variable (not true) or that it was cleaner code (I disagree).
The primary place that these initializers are useful like this is when instantiating maps, ie:
Map map = new HashMap() {{
put("key1", "value1");
put("key2", "value2");
}};
which I think actually is slightly more readable.
It is an initializer block, but not necessarily a static initializer block. It is effectively a constructor for an anonymous inner class. You will typically see this "double-brace initialization" pattern to conveniently create and populate collections:
private final Collection<Integer> FIXED_COLLECTION = Collections.unmodifiableCollection(new HashSet<Integer>()
{ // first set of braces declares anonymous inner class
{ add(1); add(2); add(3); } // second set is initializer block
});
It's an instance initialiser (not a static initialiser).
Consider the definition of a class
public class Foo {
private int i = getDefaultValue();
private static int getDefaultValue() {
return 5;
}
}
The call to getDefaultValue() that initalises i is essentially a code block that runs each time an instance of Foo is constructed. The notation extends that function to allow more complex initialisation. E.g.
public class Foo {
private int i;
{
int z = 4 + 5;
i = z + getDefaultValue();
}
private static int getDefaultValue() {
return 5;
}
}
The manner with which it is used in JMock is a trick to give expectations the look of a closure construct.
What's happening ? The outer braces create a new anonymous class derived from Exception. The inner braces define an initialiser and sets the oneOf() etc.
Why do this ? It's a one-liner trick for constructing and initialising an instance of a class. e. you sometimes see something like this:
new HashSet<String>(){{ add("one"); add("two"); }}
to initialise the contents of a collection.
Downsides ? Because you're creating an anonymous class within the containing class, that anonymous class contains a this reference to the outer class implicitly. Not normally a problem, but it can cause issues if (say) you want to serialise a class that you've constructed like this.
It's an initializer block. I can't tell what it does without looking at the rest of the code.
The trick is to imagine "new Expectation()" replaced with "class Something extends Expectation".
Anynoymous inner classes don't have a constructor, so you can define a an instance initilizer like this i.e. the inner set of braces are the instance initializers.
new Expectations() {
{
oneOf(alarm).getAttackAlarm(null);
}
}
The primary motivation behind this, I believe, is to create a new name space, in which names defined in Expection can be referenced more easily.
For example, suppose java.lang.Math is not final,
new Math()
{{
double x = sin(23.65);
double y = log(x);
...
}};
It's almost as if we have something like
with names from Math
{
double x = sin(23.65);
double y = log(x);
...
}
Related
Is there any advantage for either approach?
Example 1:
class A {
B b = new B();
}
Example 2:
class A {
B b;
A() {
b = new B();
}
}
There is no difference - the instance variable initialization is actually put in the constructor(s) by the compiler.
The first variant is more readable.
You can't have exception handling with the first variant.
There is additionally the initialization block, which is as well put in the constructor(s) by the compiler:
{
a = new A();
}
Check Sun's explanation and advice
From this tutorial:
Field declarations, however, are not part of any method, so they cannot be executed as statements are. Instead, the Java compiler generates instance-field initialization code automatically and puts it in the constructor or constructors for the class. The initialization code is inserted into a constructor in the order it appears in the source code, which means that a field initializer can use the initial values of fields declared before it.
Additionally, you might want to lazily initialize your field. In cases when initializing a field is an expensive operation, you may initialize it as soon as it is needed:
ExpensiveObject o;
public ExpensiveObject getExpensiveObject() {
if (o == null) {
o = new ExpensiveObject();
}
return o;
}
And ultimately (as pointed out by Bill), for the sake of dependency management, it is better to avoid using the new operator anywhere within your class. Instead, using Dependency Injection is preferable - i.e. letting someone else (another class/framework) instantiate and inject the dependencies in your class.
Another option would be to use Dependency Injection.
class A{
B b;
A(B b) {
this.b = b;
}
}
This removes the responsibility of creating the B object from the constructor of A. This will make your code more testable and easier to maintain in the long run. The idea is to reduce the coupling between the two classes A and B. A benefit that this gives you is that you can now pass any object that extends B (or implements B if it is an interface) to A's constructor and it will work. One disadvantage is that you give up encapsulation of the B object, so it is exposed to the caller of the A constructor. You'll have to consider if the benefits are worth this trade-off, but in many cases they are.
I got burned in an interesting way today:
class MyClass extends FooClass {
String a = null;
public MyClass() {
super(); // Superclass calls init();
}
#Override
protected void init() {
super.init();
if (something)
a = getStringYadaYada();
}
}
See the mistake? It turns out that the a = null initializer gets called after the superclass constructor is called. Since the superclass constructor calls init(), the initialization of a is followed by the a = null initialization.
my personal "rule" (hardly ever broken) is to:
declare all variables at the start of
a block
make all variables final unless they
cannot be
declare one variable per line
never initialize a variable where
declared
only initialize something in a
constructor when it needs data from
the constructor to do the
initialization
So I would have code like:
public class X
{
public static final int USED_AS_A_CASE_LABEL = 1; // only exception - the compiler makes me
private static final int A;
private final int b;
private int c;
static
{
A = 42;
}
{
b = 7;
}
public X(final int val)
{
c = val;
}
public void foo(final boolean f)
{
final int d;
final int e;
d = 7;
// I will eat my own eyes before using ?: - personal taste.
if(f)
{
e = 1;
}
else
{
e = 2;
}
}
}
This way I am always 100% certain where to look for variables declarations (at the start of a block), and their assignments (as soon as it makes sense after the declaration). This winds up potentially being more efficient as well since you never initialize a variable with a value that is not used (for example declare and init vars and then throw an exception before half of those vars needed to have a value). You also do not wind up doing pointless initialization (like int i = 0; and then later on, before "i" is used, do i = 5;.
I value consistency very much, so following this "rule" is something I do all the time, and it makes it much easier to work with the code since you don't have to hunt around to find things.
Your mileage may vary.
Example 2 is less flexible. If you add another constructor, you need to remember to instantiate the field in that constructor as well. Just instantiate the field directly, or introduce lazy loading somewhere in a getter.
If instantiation requires more than just a simple new, use an initializer block. This will be run regardless of the constructor used. E.g.
public class A {
private Properties properties;
{
try {
properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("file.properties"));
} catch (IOException e) {
throw new ConfigurationException("Failed to load properties file.", e); // It's a subclass of RuntimeException.
}
}
// ...
}
Using either dependency injection or lazy initialization is always preferable, as already explained thoroughly in other answers.
When you don't want or can't use those patterns, and for primitive data types, there are three compelling reasons that I can think of why it's preferable to initialize the class attributes outside the constructor:
avoided repetition = if you have more than one constructor, or when you will need to add more, you won't have to repeat the initialization over and over in all the constructors bodies;
improved readability = you can easily tell with a glance which variables will have to be initialized from outside the class;
reduced lines of code = for every initialization done at the declaration there will be a line less in the constructor.
I take it is almost just a matter of taste, as long as initialization is simple and doesn't need any logic.
The constructor approach is a bit more fragile if you don't use an initializer block, because if you later on add a second constructor and forget to initialize b there, you'll get a null b only when using that last constructor.
See http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html for more details about initialization in Java (and for explanations on initalizer blocks and other not well known initialization features).
I've not seen the following in the replies:
A possible advantage of having the initialisation at the time of declaration might be with nowadays IDE's where you can very easily jump to the declaration of a variable (mostly
Ctrl-<hover_over_the_variable>-<left_mouse_click>) from anywhere in your code. You then immediately see the value of that variable. Otherwise, you have to "search" for the place where the initialisation is done (mostly: constructor).
This advantage is of course secondary to all other logical reasonings, but for some people that "feature" might be more important.
Both of the methods are acceptable. Note that in the latter case b=new B() may not get initialized if there is another constructor present. Think of initializer code outside constructor as a common constructor and the code is executed.
I think Example 2 is preferable. I think the best practice is to declare outside the constructor and initialize in the constructor.
The second is an example of lazy initialization. First one is more simple initialization, they are essentially same.
There is one more subtle reason to initialize outside the constructor that no one has mentioned before (very specific I must say). If you are using UML tools to generate class diagrams from the code (reverse engineering), most of the tools I believe will note the initialization of Example 1 and will transfer it to a diagram (if you prefer it to show the initial values, like I do). They will not take these initial values from Example 2. Again, this is a very specific reason - if you are working with UML tools, but once I learned that, I am trying to take all my default values outside of constructor unless, as was mentioned before, there is an issue of possible exception throwing or complicated logic.
The second option is preferable as allows to use different logic in ctors for class instantiation and use ctors chaining. E.g.
class A {
int b;
// secondary ctor
A(String b) {
this(Integer.valueOf(b));
}
// primary ctor
A(int b) {
this.b = b;
}
}
So the second options is more flexible.
It's quite different actually:
The declaration happens before construction. So say if one has initialized the variable (b in this case) at both the places, the constructor's initialization will replace the one done at the class level.
So declare variables at the class level, initialize them in the constructor.
class MyClass extends FooClass {
String a = null;
public MyClass() {
super(); // Superclass calls init();
}
#Override
protected void init() {
super.init();
if (something)
a = getStringYadaYada();
}
}
Regarding the above,
String a = null;
null init could be avoided since anyway it's the default.
However, if you were to need another default value,
then, because of the uncontrolled initialization order,
I would fix as follow:
class MyClass extends FooClass
{
String a;
{
if( a==null ) a="my custom default value";
}
...
I want to know how many instances of a static member class can be created by the enclosing class. I assume one only, but then the following extract from Bloch doesn't make sense to me.
Quoting Joshua Bloch's Effective Java - Item 22*: Favor static member classes over nonstatic.
A common use of private static member classes is to represent components of the object represented by their enclosing class. For example, consider a Map instance, which associates keys with values. Many Map implementations have an internal Entry object for each key-value pair in the map. While each entry is associated with a map, the methods on an entry (getKey, getValue and setValue) do not need access to the map. Therefore, it would be wasteful to use a nonstatic member class to represent entries: a private static member class is best. If you accidentally omit the static modifier in the entry declaration, the map will still work, but each entry will contain a superfluous reference to the map, which wastes space and time.
He states that the map creates an Entry object for each key-value pair in the map, i.e. multiple instances of the static member class.
So my assumption is wrong! That means my understanding of static member classes is wrong. Everyone knows how a static member variable behaves, the classic static final string for instance - there is only one instance of the object.
Does this mean then that a static member class is not actually instantiated when the enclosing object is instantiated?
Well in that case, what's the point of Map using a static member class for Entry? Why not just use an interface on the API? Every other Collections class could then just provide it's own implementation.
[*] Just realised that it's item 18 in the PDF version of the book I have
This is a common misinterpretation of the static keyword.
When you use static with a variable it means there will be only one of these for all objects of this class or something like that.
static Object thereWillBeOnlyOne = new Object();
However, in the context of inner classes it means something completely different. A static inner class has no connection with an object of the enclosing class while a non-static inner class does.
A static inner class:
public class TrieMap<K extends CharSequence, V> extends AbstractMap<K, V> implements Map<K, V> {
private static class Entry<K extends CharSequence, V> implements Map.Entry<K, V> {
The Map.Entry class used by my TrieMap class does not need to refer to the object that created it so it can be made static to save the unnecessary reference.
A non-static inner class:
public final class StringWalker implements Iterable<Character> {
// The iteree
private final String s;
// Where to get the first character from.
private final int start;
// What to add to i (usually +/- 1).
private final int step;
// What should i be when we stop.
private final int stop;
// The Character iterator.
private final class CharacterIterator implements Iterator<Character> {
// Where I am.
private int i;
// The next character.
private Character next = null;
CharacterIterator() {
// Start at the start.
i = start;
}
public boolean hasNext() {
if (next == null) {
if (step > 0 ? i < stop : i > stop) {
next = s.charAt(i);
i += step;
}
}
return next != null;
}
The CharacterIterator inside a StringWalker object refers to the string to be iterated as s which only exists once in the StringWalker object. I can therefore create many iterators of a StringWalker and they all walk the same string.
Why this weirdness?
This seemingly illogical duality derives from the use of the static keyword in C.
In C you can (or at least used to be able to) do:
void doSomething () {
static int x = 1;
if ( x < 3 ) {
} else {
}
x += 1;
}
and each time you called the function, x would be as you left it last time around - incremented in this case.
The concept was that the static keyword indicated that the variable was scopefully enclosed by its enclosing block but semantically enclosed by its parent block. I.e. the above code was roughly equivalent to:
int x = 1;
void doSomething () {
if ( x < 3 ) {
} else {
}
x += 1;
}
but x was only allowed to be referenced inside the function.
Take that concept forward into Java and things now make a little more sense. A static inner class behaves exactly like it was declared outside the class while a non-static inner bonds much more tightly to its enclosing instance - in fact it can refer to the instance directly.
Also:
class Thing {
static Object thereWillBeOnlyOne = new Object();
behaves much like
Object thereWillBeOnlyOne = new Object();
class Thing {
if it were legal.
Here endeth the lesson.
I think the Java team messed up the naming on this one. A static inner class (strictly speaking their correct name is "static nested class") is in no way different from an ordinary class except it has a fancy name (Something.MyClass instead of MyClass) and can be made private (i.e. not instantiable from other classes).
In case of Map, it was solely chosen because the name Map.Entry makes it clear that Entry relates to Map. As you suggest, it would have been perfectly reasonable to just use an ordinary class for this. The only difference is you don't get to write Map.Entry.
I think what they should have done is to use the syntax for "non-static" inner classes (i.e. just class in an enclosing class) for static nested classes, and instead invent a new keyword to create "non-static" inner classes, because it's these that behave different from normal classes. Maybe something like attached class. AFAIK the keyword static was chosen in order to avoid having too many reserved keywords, but I think it just encouraged confusion.
Yes, you can have many instances of the nested class, no matter that the nested class is static.
When the nested class is static you can create instances of it without having an instance of the enclosing class, this is one of the benefits, and basically the main difference between static and non-static nested classes.
Does this mean then that a static member class is not actually instantiated when the enclosing object is instantiated?
It's instantiated when it's constructor is called. Not any different from non-static classes. The nested class itself is loaded by the JVM, when the code first accesses it. Again this is not any different when compared to other classes, I think (not 100% sure of this though, but you can test it yourself). So I think you're kind of mixing the terms "loading the class by the JVM" and "instantiating the class".
Well in that case, what's the point of Map using a static member class for Entry? Why not just use an interface on the API?
As said, it's easier to create instances of static nested classes. You don't need an enclosing instance which is sometimes (maybe most of the times) exactly what you want.
See also:
(1) Nested Classes
(2) How can the JVM decide if a class is nested into another class?
(3) Loading of a nested class by the JVM
You can search for other references along these lines.
The reference (2) seems advanced and kind of peripheral to your question.
what's the point of Map using a static member class for Entry?
That's because, it makes the package structure logically correct.
Why not just use an interface on the API?
Now, this is a design discussion nobody would like to be dragged into.
I have a class with several methods. Now I would like to define a helper method that should be only visible to method A, like good old "sub-functions" .
public class MyClass {
public methodA() {
int visibleVariable=10;
int result;
//here somehow declare the helperMethod which can access the visibleVariable and just
//adds the passed in parameter
result = helperMethod(1);
result = helperMethod(2);
}
}
The helperMethod is only used by MethodA and should access MethodA's declared variables - avoiding passing in explicitly many parameters which are already declared within methodA.
Is that possible?
EDIT:
The helper mehod is just used to avoid repeating some 20 lines of code which differ in only 1 place. And this 1 place could easily be parameterized while all the other variables in methodA remain unchanged in these 2 cases
Well you could declare a local class and put the method in there:
public class Test {
public static void main(String[] args) {
final int x = 10;
class Local {
int addToX(int value) {
return x + value;
}
}
Local local = new Local();
int result1 = local.addToX(1);
int result2 = local.addToX(2);
System.out.println(result1);
System.out.println(result2);
}
}
But that would be a very unusual code. Usually this suggests that you need to take a step back and look at your design again. Do you actually have a different type that you should be creating?
(If another type (or interface) already provided the right signature, you could use an anonymous inner class instead. That wouldn't be much better...)
Given the variables you declare at the top of your method can be marked as final (meaning they don't change after being initialized) You can define your helper method inside a helper class like below. All the variables at the top could be passed via the constructor.
public class HelperClass() {
private final int value1;
private final int value2;
public HelperClass(int value1, int value2) {
this.value1 = value1;
this.value2 = value2;
}
public int helperMethod(int valuex) {
int result = -1;
// do calculation
return result;
}
}
you can create an instance of HelperClass and use it inside the method
It is not possible. It is also not good design. Violating the rules of variable scope is a sure-fire way to make your code buggy, unreadable and unreliable. If you really have so many related variables, consider putting them into their own class and giving a method to that class.
If what you mean is more akin to a lambda expression, then no, this is not possible in Java at this time (but hopefully in Java 8).
No, it is not possible.
I would advise you create a private method in your class that does the work. As you are author of the code, you are in control of which other methods access the private method. Moreover, private methods will not be accessible from the outside.
In my experience, methods should not declare a load of variables. If they do, there is a good chance that your design is flawed. Think about constants and if you couldn't declare some of those as private final variables in your class. Alternatively, thinking OO, you could be missing an object to carry those variables and offer you some functionality related to the processing of those variables.
methodA() is not a method, it's missing a return type.
You can't access variables declared in a method from another method directly.
You either has to pass them as arguments or declare methodA in its own class together with the helpermethods.
This is probably the best way to do it:
public class MyClass {
public void methodA() {
int visibleVariable=10;
int result;
result = helperMethod(1, visibleVariable);
result = helperMethod(2, visibleVariable);
}
public int helperMethod(int index, int visibleVariable) {
// do something with visibleVariable
return 0;
}
}
public class A{
}
A a = new A(){{
final int x = 1; // IT HAS TO BE FINAL HERE. WHY?
}};
A aa = new A(){
int x = 1; // THIS NEED NOT BE FINAL. WHY?
final int y = 1; // STILL FINAL IS ALLOWED HERE. WHY?
public int getX(){
return x;
}
};
Can somebody please answer the questions mentioned inside the snippet?
Thanks
The outer set of {} declares an anonymous subclass
The inner set declares an initialization block within that subclass.
With the following example, it becomes easier to understand what's going on:
List<String> strings = new ArrayList<String>() {{
add("string");
add("another string");
}};
You basically say: I want a subclass of List, which calls method add at initialization.
It's similar to:
List<String> strings = new ArrayList<String>();
strings.add("string");
strings.add("another string");
A a = new A(){{
final int x = 1; // IT HAS TO BE FINAL HERE. WHY?
It needn't.
The difference between the two is that in the first case, you're writing the code used to initialize each object in the double braces. That x is its local variable (doesn't have anything to do with objects of class A).
In the second case, you're defining the classes body. x would be its member variable. If it were static, its class variable. If final a (basically) constant.
I wonder, why would you want to use the first version of the code (the one with {{}}). The x variable declared inside it's not useful at all, it's local only to the block scope in which it was defined, and being inside an anonymous class, you won't be able to reference it anywhere in the code.
And anyway, the first version of x declaration does not need to be final, it compiles just as fine, with or without final.
In your first example the inner braces create something called an instance initializer. It's an obscure way to initialize variables and call instance methods when an object is constructed. So the first example creates an anonymous subclass of A and creates a local variable within the scope of the initializer. It doesn't have to be final.
In the second example you're creating an anonymous subclass of A but not creating an instance initializer, the variables you create are instance variables of the anonymous subclass.
The first instance A a = new A(){{... has an initialisation block inside the declaration. Another way of writing it would be like this:
A a = new A()
{
{
final int x = 1; // This is inside an initialisation block
}
};
Changing the formatting makes it a bit more obvious.
$ javac InitInt.java
InitInt.java:7: variable right might not have been initialized
InitInt(){}
^
1 error
$ cat InitInt.java
import java.util.*;
import java.io.*;
public class InitInt {
private final int right;
// Design Problem?
// I feel the initialization problem is just due to bad style.
InitInt(){}
InitInt{
// Still the error, "may not be initialized"
// How to initialise it?
if(snippetBuilder.length()>(charwisePos+25)){
right=charwisePos+25;
}else{
right=snippetBuilder.length()-1;
}
}
public static void main(String[] args) {
InitInt test = new InitInt();
System.out.println(test.getRight());
}
public int getRight(){return right;}
}
Partial Solutions and Suggestions
use "this" to access methods in the class, instead of creating empty constructor
change final to non-final
with final field value: initialize all final values in every constructor
remove the empty constructor, keep your code simple and clean
You mean define, not initialize. The problem you're having (after that pretty radical edit) is you're defining a constructor that doesn't initialize a final variable, which Java doesn't allow -- all finals need to be initialized by the time the instance is finished constructing. Either initialize it in your constructor, or make it non-final
Yeah, the problem is that one of your constructors doesn't initialize the final field. In Java final non-static fields have to be initialized at the declaration time, in an initialization block, OR in EVERY constructor! The default constructor in your example doesn't do that.
Remember as well that implementing an empty default constructor makes sense only if you want to use inheritance features. If you don't provide a default constructor, but you will some other one Java won't make a hidden default constructor for you, because the default one is not required. So don't implement things like MyClass() {} with no special purpose - keep your code clean and save!
You can't use new with int. int is a primitive, and new is an object operator. Consider using Integer instead, or just assigning an integer literal to it.
There's nothing wrong with your if-else statement, and nothing wrong with initializing a final variable within a branching statement in a constructor. I just ran a simple constructor like yours to initialize private int right and it worked fine. Make sure that you are declaring your constructor correctly, as InitInt() { ... }.
The error you posted is because you have in your code InitInt(){}, an empty constructor that does not initialize right. You need to initialize final fields in this and all constructors.
Your constructor is absolutely Okey!!!! The problem is that you left the "right" variable uninitialized.
You have to initialize the "right" variable:
private final int right = 0;
If you only try to access the methods in the class, use this, instead of creating empty-constructor for it:
import java.io.*;
import java.util.*;
public class FileDir {
private ArrayList<Integer> lineNumbers;
FileDir(Integer nth){
lineNumbers=new ArrayList<Integer>();
lineNumbers.add(nth);
// You don't need an empty constructor
// to call class methods, use "this"
this.printHello("Davids");
}
public static void main(String[] args) {
FileDir test = new FileDir(7);
ArrayList<Integer> inteTest=test.getLineNumbers();
for (Integer i : inteTest)
System.out.println(i);
}
public void printHello(String name) { System.out.println("Hello "+ name); }
public ArrayList<Integer> getLineNumbers() { return lineNumbers; }
}