1

I have this:

public void log(Circle circOrig) {
    ...
}

And I'm trying to avoid doing this:

private void addPositions(PositionsLogger positionsLogger) {
    ...
    Circle circ = new Circle(0,0,0); //`circ` could be final
    circ.setPosition(0,0);
    posLogger.log(circ);
    ...
}

By doing this:

public static void main(String[] args) {
    ...
    posLogger.log(new (Circle(0, 0, 0).setPosition(0, 0)));
    ...
}

Which is obviously a compile error because log() requires a Circle, not a void.

How can I avoid having to declare a local variable for such a trivial purpose?

deinocheirus
  • 1,833
  • 5
  • 26
  • 44
  • 7
    Make `setPosition()` return `this`. – Sotirios Delimanolis Oct 02 '13 at 14:24
  • @SotiriosDelimanolis fixed, sorry. I guess it's not possible to do what I want to do without modifying the class Circle, isn't it? – deinocheirus Oct 02 '13 at 14:25
  • if you are using new, that means you are creating an object whether you assign it to a reference or not. – Juned Ahsan Oct 02 '13 at 14:26
  • 2
    Indeed, you won't be able to without some changes to the class. But honestly, what's the problem with declaring a variable? – Sotirios Delimanolis Oct 02 '13 at 14:27
  • 1
    Never do what @SotiriosDelimanolis said, returning this from a setPositions is not the proper way to develop. – RamonBoza Oct 02 '13 at 14:27
  • 1
    @RamonBoza That's just not true. Heard of builders? http://stackoverflow.com/questions/5007355/builder-pattern-in-effective-java – Oskar Kjellin Oct 02 '13 at 14:28
  • 3
    @RamonBoza I point you to [the Fluent interface](http://en.wikipedia.org/wiki/Fluent_interface) (though personally I'm not a big fan). – Bernhard Barker Oct 02 '13 at 14:28
  • @OskarKjellin This is not a builder, is a concrete Class, a builder would be new CircleBuilder(x,y).setZ(z).setA(a).build() – RamonBoza Oct 02 '13 at 14:29
  • @RamonBoza True, but builders often return this – Oskar Kjellin Oct 02 '13 at 14:29
  • @OskarKjellin ofc, they shall return this, but this is not a builder :P – RamonBoza Oct 02 '13 at 14:30
  • @RamonBoza still, your statement was never do that – Oskar Kjellin Oct 02 '13 at 14:31
  • @RamonBoza Please explain why. What's the problem with returning `this`? – Sotirios Delimanolis Oct 02 '13 at 14:31
  • You can use *Builder pattern*. If you can't modify `Circle`, you can have the `Builder` class outside the `Circle`. But it's just a way of doing it. I would never, even in my dreams do something like this to avoid the problem you are specifying (the *avoid use of local variable*). – Rohit Jain Oct 02 '13 at 14:32
  • @SotiriosDelimanolis this is a Bean, an entity class that shall be final, immutable one, so returning this is out of the scope. I shall only return this for Builders, Singleton, and some other design patterns. – RamonBoza Oct 02 '13 at 14:34
  • @RamonBoza Where are you getting that it's immutable? There's clearly a `set` method right there. How is returning `this` out of scope? You already have a reference to the object if you are calling the method on it. If it makes your life easier, use it. I'm not suggesting it's better in this case. – Sotirios Delimanolis Oct 02 '13 at 14:35

4 Answers4

6

There is no reason why not to have local variable. When you call new, It will create new object either way. Solution without local variable is more messy and less readable.

Variable is just pointer to memory, where "circle" is allocated. So when passing argument to your log function, you pass that pointer and inside log, you are working with created circle instance. There is no deep copy.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Martin Perry
  • 9,232
  • 8
  • 46
  • 114
1

If you really want to not have a local variable, you can override the circle class like so:

posLogger.log(new (Circle(0, 0, 0){{setPosition(0, 0);}}));
mbumiller
  • 114
  • 2
  • 6
  • I don't like this solution for two reasons. First, overriding the method you fix the position of the circle, which may need to be moved in other parts of the code. Second, you make two of the three Circle constructor parameters redundant leaving room for inconsistencies. – mariosangiorgio Oct 02 '13 at 14:31
  • @mariosangiorgio how can you move a circle later without having a variable pointing to it? How do you know what the constructor parameters do? You haven't seen the code. They're not redundant. – deinocheirus Oct 02 '13 at 14:36
  • Probably in this case you're right that the Circle it is not going to be moved. But how can we know that `log`, which has a reference to the object, does not move it? We don't have that method's code neither. Probably in this case the solution is going to provide the required behavior, but I am convinced that it is ugly and goes against best practice of programming. I assumed `Circles` constructor to require position and radius, as it happens in common implementation of circles. – mariosangiorgio Oct 02 '13 at 14:42
  • 1
    @mariosangiorgio - minor point but that is not actually overriding the setPosition method. It is making a call to setPosition so you can happily call setPosition again from another part of the code (assuming you can get a reference to the circle of course) – matt helliwell Oct 03 '13 at 09:51
1

Assuming you don't have access to the Circle code and don't like the overriding mechanisms (which look as ugly as having a local variable so are a bit pointless) then all you can do is define a helper method that creates the circle, sets its position and returns the circle.

I can understand why you want to do this but I think with Java being what it is, you're not going to get a brilliant solution without access to the Circle code.

matt helliwell
  • 2,574
  • 16
  • 24
0

As an alternative solution you should consider extend Circle adding a new constructor that does what you need.

You could either do that in the code of the class, if you can modify it, or in a new class.

public class ExtendedCircle extends Circle{
    public class ExtendedCircle(int x, int y, int x, int positionX, int positionY){
            super(x,y,z);
            setPosition(positionX, positionY);
    }
}

Note that I don't think that the creation of a new class is an ideal solution. It would be better to have an helper method or to keep the reference to the variable as reported in other answers.

mariosangiorgio
  • 5,520
  • 4
  • 32
  • 46