0

So I have this Contructor:

 public MyClass(boolean done, int lvl , String s, int x, int y, Skill parent, Item item, int cost) {
    this.done = done;
    this.lvl = lvl;
    this.name = s;
    this.Xpos = x;
    this.Ypos = y;
    this.parent = parent;
    this.item = item;
    addSkill(this, s);
}

Is there a way for me to use/initialize this in another class without having to do

MyClass myclass = new MyClass(false, 0, "", 0, 0, null, this.item, 1)

If I just do

MyClass myclass;

Then I get the "horrid" null pointer exception.

Dennis Meng
  • 5,109
  • 14
  • 33
  • 36
Snhp9
  • 511
  • 1
  • 6
  • 21
  • Create a parameter-less second constructor? – Andrew Martin Aug 20 '13 at 17:17
  • You can use `Dependency Injection` or create a factory method – Raghav Aug 20 '13 at 17:17
  • write another constructor that invokes that one, providing some default arguments. – roippi Aug 20 '13 at 17:17
  • 1
    I think you misunderstand what the left hand side, `MyClass myclass`, is doing. You are declaring space in memory to fit an object of the `MyClass` size. You're calling the location of this space `myclass`. But you're not _putting_ anything in that space. It's null - thus the null pointer exception. You need to construct an object and assign it to that space (eg. `MyClass myclass = new MyClass();`). The only way you can make an object is to construct it - so you can never initialize a class without a constructor. – sdasdadas Aug 20 '13 at 17:48
  • `MyClass myclass` is just a reference. If you want an instance of an object, you have to create one. – Peter Lawrey Aug 20 '13 at 17:53

5 Answers5

3

It sounds like you want to create a second constructor that takes no parameters.

You can then write

MyClass myclass = new MyClass();
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Would the constructor just be a blank field? – Snhp9 Aug 20 '13 at 17:17
  • @Snhp9 It would call your current constructor with the default values. However, note that you probably need at least one parameter, since there's an object reference being passed in for `item`. – Michelle Aug 20 '13 at 17:19
  • may I post in a comment the class that I am dealing with? – Snhp9 Aug 20 '13 at 17:22
  • @Snhp9 you need to declare the 0-pm constructor in your class before using it. – Arpit Aug 20 '13 at 17:22
2

I recommend you implement something akin to the Builder Pattern. It is very versatile. You can read more about the Builder Pattern on Wikipedia.

Community
  • 1
  • 1
Engineer2021
  • 3,288
  • 6
  • 29
  • 51
0

MyClass myclass; is just a reference. You need to bind it with some object. No use of remote control without television. What else you can try to short your constructor is just provide a 0 parameter constructor.

 public MyClass() {
    this.done = "default";
    this.lvl = "default value";
    this.name = "default value";
    this.Xpos = "default value";
    this.Ypos = "default value";
    this.parent = "default value";
    this.item = "default value";
}

Now you can do like this MyClass mcRef=new MyClass();

Arpit
  • 12,767
  • 3
  • 27
  • 40
0

It sounds like you might want some "default arguments". In Python, you could do something like this:

class MyClass:
    def __init__(done=false, load=1, ...):
        self.done = done
        self.load = load
        # ...

a_new_instance = MyClass(done=true)

Basically, all of your variables start out with a default value - but you can change them if you are so inclined.

In Java, it is a little different:

class MyClass {
    private boolean done = false; // Notice the default value for done will be false
    // ... you would list (and instantiate!) the rest of your variables

    public MyClass() {}

    public MyClass(boolean done, int lvl, ...) {
         this.done = done;
         // ...
    }
}

In this way, you are only forced to call the constructor if you want to change the default values. But what happens if you only want to change 1 or 2 values? Well, you could make new constructors:

public MyClass(boolean done) { this.done = done; }
public MyClass(boolean done, int lvl) { this.done = done; this.lvl = lvl; }

but this will quickly get out of hand!

So, to get around this, we can use a "builder" pattern. That will look something like this:

public class MyClass {
    private boolean done;
    private int lvl;

    // Now the constructor is private and takes a builder.
    private MyClass(MyClassBuilder builder) {
        // ... and your variables come from the ones you will build.
        this.done = builder.done;
        this.lvl = builder.lvl;
        // ...
    }

    public static class MyClassBuilder {
        // The builder also has the same members.
        private boolean done;
        private int lvl;

        // Notice that we return the builder, this allows us to chain calls.
        public MyClassBuilder done(boolean isDone) {
            this.done = isDone;
            return this;
        }   

        public MyClassBuilder level(int level) {
            this.lvl = level;
        }

        // And a method to build the object.
        public MyClass build() {
            MyClass mc = new MyClass();
            mc.done = this.done;
            mc.lvl = this.lvl;
            // ... copy over all your variables from the builder to the new class
            return mc;
        }
    }
}

So, now when we want to instantiate a MyClass object we can do this:

MyClass mc = MyClassBuilder.done(false);

or, we can chain the calls:

MyClass mc2 = MyClassBuilder.done(true).level(4). // ... you can go on for a while

As an aside, sometimes having more than three or four variables in a class is a sign that the class is doing too much. If the class has more than one "responsibility", you should break it up into a few smaller classes. Then you won't need a builder class.

sdasdadas
  • 23,917
  • 20
  • 63
  • 148
0

This is not C++. Default values for all references is null. If you do not use new, the object remains null.

There are several methods of initialization if you dislike multi-parameter constructors. You can have setters return this and chain initialization like:

Person p = new Person().setAge(18).setName("Tom").setHeight(175);

or even simply

Person p = new Person().age(18).name("Tom").height(175);

Such method is not very common but definitely is easy to read and difficult to make mistake with.

You can also use static factory methods, like

class Person {

  private Person() {} // mark as private to force  creation with static method

  public static Person create() {
    Person p = new Person();
    //fill default values?
    return p;
  }
}
Dariusz
  • 21,561
  • 9
  • 74
  • 114