There are two special methods, which are used to initialize a class and its objects.
The init method is used to initialize a class, and in particular to initialize the values of any static variables. It is called automatically the first time that one of the class’s (static) fields is accessed, or when an instance of the class is created.
Some other points to note about init :-
init methods (if any) are called before the class’s.init method is only ever called once.init method must be declared as a private static method.init field via normal field access, so the method can only ever be invoked by the runtime system itself. There is however a library function, lang.Class.ensure_initialized() which will ensure the given class’s init method has been called, if it hasn’t been already.init may not be called if a constant field access has been replaced by the value assigned to it in init, during optimization. For example, we may have a class X with a constant Y, assigned the value 123 in X’s init method. Elsewhere in the program, the expression X.Y would be replaced with 123, by oit’s optimizer. When encountered at runtime, 123 would not of course cause X’s init method to be run.const fields can only be assigned to from within the init method. In other words, you cannot call another method from init and initialize constants there. This restriction is to help oit in the constant folding process just described.The new method is used to initialize an object, ie an instance of a particular class. The method is not invoked explicitly however. Rather, in order to create an instance the class name is used like a function call, and the new() method is invoked automatically. So for example :-
import io
class X()
public new(a, b)
write("in new a=", a, " b=", b)
return
end
end
procedure main()
local i
i := X(3, 4)
end
This writes "in new a=3 b=4".
Some other points to note about new() :-
new() method. If it is absent, then all the instance variables are initially &null.new() method in a superclass, just like any other method.new() method is respected. So making the new() method private means that instances can only be created from within the class itself (by necessity in a static method).After an object has been initialized, the new() method cannot be accessed, and any attempt to do so gives a run-time error. So in the example above, the following would not be allowed :-
procedure main()
local i
i := X(3, 4)
i.new(5, 6) # Runtime error
endIf the new() method fails, then the creation of the object fails. This gives new() extra control over the creation process, but does mean that you have to remember to put a return in the new() method somewhere.
It is sometimes desirable to provide a way of creating a new instance which bypasses the new() method. The method lang.Class.create_instance() provides a way to do this. It can be called from within a class, and it returns a new instance of that class. new() is not invoked, and all of the instance variables are set to &null. It is the responsibility of the caller to initialize the instance as appropriate.
Another method, lang.Class.create_raw_instance(), is just like create_instance(), except that the new object is in an even more primitive state, which allows const fields to be assigned and new to be invoked. The method lang.Class.complete_raw_instance() must be used to complete the object’s initialization.
Here is an example illustrating the use of create_instance().
import io, lang
class X()
private x
public static f(x)
local i
write("In X.f()")
i := Class.create_instance()
i.x := 2 * x
return i
end
public new(x)
write("In X.new()")
self.x := 3 * x
return
end
end
procedure main()
write(to_string(X(123)))
write(to_string(X.f(345)))
end
The output is :-
In X.new()
object X#1(x=369)
In X.f()
object X#2(x=690)
Contents