Calling a function from a constructor - java

How can I have the Edit() method be called by default when I construct a Breuk object?
public class Breuk {
public Breuk() {//constructor
}
private static Breuk Edit (Breuk b){ //function
}
}

Every time a new Breuk object is created, the Edit() method is called by default since it is placed inside the constructor. As the method is static, it has to be called in a statically way, i.e. ClassName.staticMethod(). As the method expects a Breuk object as argument, you pass this reference to it, meaning the object that's being constructed.
By the way, all method names should be lowercase according to Java conventions. So, consider renaming Edit(...) to edit(...).
class Breuk {
int x;
int y;
public Breuk(int x, int y) {
Breuk.Edit(this);
}
private static void Edit(Breuk b){
//edits breuk
}
}

First of all, you should stick to Java naming conventions, which state that method names should be lowerCamelCase. So you should rename your Edit() method to edit().
If you want the edit() method to be called by default when constructing an instance of the Breuk class, you can use an initializer block.
Excerpt from the Java Tutorial:
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
For your example, you could try something like this:
public class Breuk {
{ // initializer block
Breuk.edit(this); // always called by default,
// no matter which constructor is used
}
public Breuk() { // no-args constructor
}
public Breuk(int a1, int a2) { // another constructor
}
private static Breuk edit(Breuk b) { // function
}
}
Here I'm assuming you want to pass the instance being constructed to the edit() method, that's why this is passed as an argument.
EDIT:
In case this assumption is true, I suggest you make the edit() method return void, as you can't assign an instance to this, since it's final (and it doesn't make any sense, either).

Just call the method from the end of your default constructor. There's no need to think about any "default" calling here. Just implement it.
public class Breuk {
public Breuk() {
// constructor
edit(this);
}
private static Breuk edit (Breuk b){
// class-level processing on any Breuk that is constructed
}
}

Related

How do you create an instance variable to call a non-static method from another class?

class V
{
void print_V(int number)
{
String v= "v";
int count= number;
System.out.print("Letter" + v.repeat(count));
}
void print_V()
{
System.out.print("v");
}
public static void call_Print_V(int n)
{
print_V(n);
}
}
class Main
{
public static void main(String[] args)
{
v call_Print_V = new v();
call_Print_V.print_V(input);
}
}
I tried searching on the Internet for how to create instance methods but found none of them helpful. I tried to format the instance method in a similar way to the examples that I found but I still couldn't get my method to be called.
Try to make the method you want to call public. I assume this is Java.
So instead of:
void print_V()
do:
public void print_V()
Methods of classes are private by default. Private methods can not be called outside of their class scope.
Also, I would consider not declaring public or private bad practise. Same goes for snake case, so please read the following article about code conventions. It makes live for other programmers a lot easier.
https://www.geeksforgeeks.org/java-naming-conventions/
You are trying to call print_V in a non static context.
Give your class a constructor and call the method from the constructor.
Also, the recursive class initialzer call in main only needs to be
new V();
You can refer to your class in there as "this" (keyword) so no reference required if you make an ondestroy listener method for System.exit()
Also, input variable looks like it should be args[1] from main array argument to feed into constructor as argument
new V(new Integer(args[1]).intValue());
An instance variable is any non-static variable "created as a global at construction time".
It usually is initialised in a constructor, or remains null until something wants to use it. Only globals, instance variables in the class, can remain null until they are required for use.
import W;
class V{
W otherclass; // non static instance variable a global
boolean startedW = false; // non static instance variable a global
int arg1; // this classes non static instance variable a global
// a constructor is for when a class starts
// constructor a constructor is NOT a method only a class initializer
V(int arg1){ // any arguments fed to the class go in the ellipses curved brackets
this.arg1 = arg1;
otherclass = new W();
startedW = true;
// next line calls a method from class W
T typo = otherclass.someMethodToCall();
// would probably follow is more work here but...whatever
}// end of constructor 1
// constructor overloading , a second constructor
V(String args1){
arg1 = new Integer(args1).intValue();
} // end constructor 2
public static void main(String args[]){
// doing anything much in main is difficult
// because of non static context errors for variables and methods
new V(args[1]);
}
}// end class

Java method call in constructor chaining

Is it possible to call a constructor with the result of a method from another constructor of the same class?
I want to be able to accept input in several forms, and have something like:
public class MyClass
{
public MyClass(int intInput)
{
...
}
public MyClass(String stringInput);
{
this(convertToInt(stringInput));
}
public int convertToInt(String aString)
{
return anInt;
}
}
When I try to compile this, I get
error: cannot reference this before supertype constructor has been called
refering to convertToInt.
You just need to make convertToInt static. Since it doesn't really rely on on anything in the class instance, it probably doesn't really belong on this class anyway.
Here's an example:
class MyClass {
public MyClass(String string) {
this(ComplicatedTypeConverter.fromString(string));
}
public MyClass(ComplicatedType myType) {
this.myType = myType;
}
}
class ComplicatedTypeConverter {
public static ComplicatedType fromString(String string) {
return something;
}
}
You have to do it this way because, behind the scenes, the super-constructor (in this case Object) needs to be called before your own constructor is run. By referring to this (via the method call) before that invisible call to super(); happens you're violating a language constraint.
See the JLS section 8.8.7 and more of the JLS section 12.5.
The method convertToInt can't be called, because it needs to be run by an object, not just from a class. Therefore, changing the code to
public static int convertToInt(String aString)
{
return anInt;
}
means that convertToInt before the constructor has finished.
No its not possible. To call instance method all your super class constructor must have been called. In this case you are calling this() which replaces call to super(). You can not have both super() and this() in the same function either. So super class instance is not initialized in your case hence you are getting this error.
You can call like this
public MyClass(String stringInput) {
super(); // No need to even call... added just for clarification
int i = convertToInt(stringInput);
}
Making the method static might solve your problem.

Can I call a method before a constructor

I know I can call static methods inside a constructor.
I have one contructor in one class which is calling another constructor through this(arguments).
Secondly that second constructor is calling super(arguments) calling super constructor.
I want to execute some code before these constructors execute. I cannot use a static block. Any ideas?
You can call static methods. I often do it like this:
public class MyClass extends SuperDuperClass {
public MyClass() {
this(convert("Foo!")); // convert will be executed
// other constructor is called
}
public MyClass(String arg) {
super(convert(arg)); // convert will be executed
// before superconstructor is called
}
private static String convert(String arg) {
return arg + "_modified";
}
}
Of course, we can't call instance methods or use non static fields.
(and, of course, this pattern requires a constructor on super that takes parameters)
The super() call has to be the first statement in a constructor, no exceptions apart from statics which you've already mentioned you can't use.
Even when you don't explicitly write a super() call at the start of your constructor, the compiler puts it in for you. It's always there!
Your best bet is to refactor your code so you don't feel the need to call anything before the super() call, but without seeing the code (or at least more context behind it) no-one can tell you how is best to do that!
You can't - the first thing java needs is a super.constructer call - written or not!
Use the factory pattern so you can do this:
public static MyObject newInstance() {
staticMethod();
return new MyObject();
}
Assuming the static method isn't supposed to actually change how the constructor behaves, that will literally call it before the constructor is executed.
You can do this, also without a static block:
public Main() {
System.out.println("Inside Constructor");
}
{
System.out.println("Before Constructor");
}
public void doTest() {
this.doTest();
}

What is the return type of a constructor in java?

As we know that we do not have to add any return type to a Java constructor.
class Sample{
.....
Sample(){
........
}
}
In Objective C, if we create a constructor, it returns a pointer to its class. But it is not compulsory, I think.
AClass *anObject = [[AClass alloc] init];//init is the constructor with return type a pointer to AClass
Similarly, Is the constructor converted to a method which return a reference to its own class??
Like this:
class Sample{
.....
Sample Sample(){
........
return this;
}
}
Does the compiler add a return type a reference to same class to constructor?
What is happening to a constructor?
Any reference to study this?
EDIT:
Actually i want the answers to be at byte code level or JVM level or even below.
Many have answered how constructors are defined in Java.
At the JVM level, static initialisers and constructors are methods which return void. Static initialisers are static methods, however constructors use this and don't need to return anything. This is because the caller is responsible for creating the object (not the constructor)
If you try to only create an object in byte code without calling a constructor you get a VerifyError. However on the oracle JVM you can use Unsafe.allocateInstance() to create an object without calling a constructor,
The static initialiser is called <cinit> which takes no arguments and the constructor is called <init>. Both have a void return type.
For the most part, this is hidden from the Java developer (unless they are generating byte code) however the only time you see these "methods" in stack traces (though you can't see a return type)
While constructors are similar to methods, they are not methods. They have no return type, are not inherited, and cannot be hidden or overridden by subclasses.
Constructors are invoked by class instance-creation expressions (basically, the use of new), by explicit invocation from other constructors (using this(...) or super(...) syntax), and by the string concatenation operator. There is no other way to invoke a constructor (in particular, they cannot be invoked like other methods).
See Section 8.8 of the Java Language Specification for more info.
Is the constructor converted to a method which return a reference to its own class??
No but yes, if it is specified to do so.
Does compiler add a return type a reference to same class to constructor ??
No it does not
What is happening to a constructor??
It is the method, which runs when the object is created. Typically, by using "new" keyword. It Might perform some preliminary task, or return something or assign some values during construction.
Any reference to study this.??
http://www.javaworld.com/javaworld/jw-10-2000/jw-1013-constructors.html
http://www.javabeginner.com/learn-java/java-constructors
Constructors are similar to methods except that they use the name of the class and have no return type. The whole purpose of using constructors is to create an object (an instance of a class) and allocate it (via new keyword) in the memory (the heap) and also initialize any fields if available.
Constructors are invoked via the special java keyword new, which creates (and initializes) an object of the specified concrete type.
I suppose you could say the combination of new and the chosen constructor "returns" an object, which in java is of course a pointer under the covers
Constructor returns the class reference of the class for which its being called.E.g.-
class A {
int x;
A(int a) {
x = a;
}
}
class B {
public static void main(String asd[]) {
A a = new A(4);
System.out.println(a);
}
}
Here after calling the constructor A(...), this constructor will return the reference of type of class A to caller( i.e. A a = new A(4) ).
The return type of the constructor is corresponding class type.
package com.ie.test;
import java.lang.reflect.*;
public class a {
public a() {
super();
System.out.println("*** no-arg constructor ***");
}
public static void main(String[] args) {
Constructor[] constructors = a.class.getConstructors();
for (Constructor constructor:constructors) {
int i = constructor.getModifiers();
AnnotatedType annotatedType = constructor.getAnnotatedReturnType();
System.out.println("***********Returntype *******"+annotatedType.getType());
System.out.println("*******constructor *****"+Modifier.toString(i));
}
Method[] methods = a.class.getDeclaredMethods();
for (Method method:methods) {
int i = method.getModifiers();
// Class c = method.getReturnType();
AnnotatedType annotatedType = method.getAnnotatedReturnType();
System.out.println("***********Returntype *******"+annotatedType.getType());
// System.out.println(c);
System.out.println("*******methods*******"+Modifier.toString(i));
}
}
public int m1() {
System.out.println("***************");
return 0;
}
}

Java passing subclass instance data to superclass constructors

Does anybody know if there's a way in Java to set the value of an instance variable in a subclass before calling the superclass constructor. I have a brief schematic below of what I'm trying to accomplish -- I need to set up the instance variables defined in the superclass differently depending on the subclass type, but I still want to be able to share common non-constructor code among different instances of the subclass.
Is there any clean way to do this, maybe some sort of coding pattern that I'm missing or something? Thanks in advance for any ideas.
public abstract class ConstraintSatisfactionProblem {
final Set<Variable> variables;
final Set<Constraint> constraints;
public Foo() {
this.variables = setupVariables();
this.constraints = setupConstraints();
}
public abstract Set<Variable> setupVariables();
public abstract Set<Constraint> setupConstraints();
public Map<Variable, Constraint> solve() { ... }
}
public class WordSquare extends ConstraintSatisfactionProblem {
final int size;
final static Set<Character> domain = ...;
public WordSquare() {
super(); // can I simulate calling super() after setting this.value = 4?
this.value = 4;
}
public Set<Variable> setupVariables() {
this.variables = new HashSet<Variable>();
for(int row = 0; row < size; ++row) {
for(int col = 0; col < size; ++col) {
variables.add(new Variable<Pair, Character>(new Pair(row, col), domain);
}
}
return this.variables;
}
public Set<Constraint> setupConstraints() {
// setup code specific to this problem
}
}
public class Cryptarithmetic extends ConstraintSatisfactionProblem {
final String problem;
public Cryptarithmetic(String problem) {
super();
this.problem = problem;
}
public Set<Variable> setupVariables() {
this.variables = new HashSet<Variable>();
for(char c : problem.toCharArray()) {
variables.add(new Variable<Character, Integer>(c, getDomain());
}
}
return this.variables;
}
public Set<Constraint> setupConstraints() {
// setup code specific to this problem
}
}
Firstly, please don't.
Secondly, really it's a really bad idea. Don't. Think about what you are trying to do in a broader context.
If you absolutely must do, you can stash it in a ThreadLocal. You can call a (non-instance) method by evaluating an expression the result of which is passed to a super() or this() (possibly the only reason why you need a second, private constructor that possibly takes a Void (capital 'V') argument). It's so evil, I am not going to even write the code down.
In your edited example code, just pass the sets into a protected constructor. If you have many arguments possibly some subclasses being special about some arguments, you might want to wrap all the arguments into a single argument object.
There is another really hacky approach, so long as you have -target 1.4 or later (which you should do!). Make the subclass an inner class (possibly anonymous). The references to the outer this and other captured variables are available before calling the super constructor.
public class Outer {
// What a hack!
private static abstract class Base {
Base() {
hello(); // Calling a virtual method in a constructor - poor form.
}
abstract void hello();
}
public static void main(String[] args) {
// Do not do this.
final String hi = "Hi!";
new Base() {
void hello() {
// Really, don't do it.
System.err.println(hi);
}
};
}
}
Place the common code you want to run in a protected method instead of in the constructor. Call that method when you wish.
You should never call any "alien" method (ie. overridable method of this class, or any method from any other class) form within a constructor. As long as the object is not fully initialized, you may have side-effects like the one you see.
In your case, in the subclass constructor, super() is called even before the "value" is set to 4. This means, the superclass constructor is called, then calls the "setup" method, while the "value" is still at 0.
Only once the superclass constructor returns, the "value" is set to 4. And it's too late then.
What I would recommend, is to set the "o1" variable to protected, so that subclasses can set its value themselves.
In Java, if you want to call a base class's constructor, you have to do it on the first line of your sub-class's constructor. So the answer is no, you can't set this.value before calling the super class's constructor.
But your sub-class's setup() method is already called in the super's constructor. Why don't you set your value there?
UPDATE:
Sorry, I didn't pay attention that your 'setup()' method returns a value. What you could do is make an abstract init() method in your super class, and call it in your super constructor before you call the setup() method. This way sub-classes will be forced to implement init(), and you would know that that is the place to initialize any sub-class's members before they are used in your super-class.
That being said, this approach does not force safety on you. When you call the super constructor from your sub-constructor, the sub-class instance is just starting to get created. It still needs to run the rest of the code in the sub-constructor before the object is safely created.
And in this situation, the super-constructor goes and calls the init() method on your just-in-the-process-of-creation sub-class. This means that if you go with approach, you have to be extra careful about what you do in the init() class.
Like others have said, don't do this. If you want to share some code between these classes, try containment/encapsulation instead of inheritance.
public class Foo {
private final Object o1;
public Foo(Object o) {
o1 = o;
}
public void complexMethodCommonToAllSubclassesOfFoo() { ... }
}
public class Bar {
private final int value;
private final Foo foo;
public Bar() {
super();
this.value = 4;
this.foo = new Foo( new Object() ); // or whatever
}
// If you need to expose complexMethodCommonToAllSubclassesOfFoo to clients of this class, just add the method and delegate to foo like this
public void complexMethodCommonToAllSubclassesOfFoo() {
foo.complexMethodCommonToAllSubclassesOfFoo();
}
}
I need to set up the instance variables defined in the superclass differently depending on the subclass type, but I still want to be able to share common non-constructor code among different instances of the subclass.
In that case, create a protected constructor in the superclass, and pass all of the customized values to it when you construct the subclass.

Categories