1

Just like this :

class Car {
    int carId;
    String brand;
    public Car(int carId, String brand) {
        this.carId = carId;
        this.brand = brand;
    }
    // getter and setter
    public String toString() {
        return " car :" + "id - " + carId + ", brand - " + brand;
    }
}
public class User {
    String name;
    Car car;
    // getter and setter
    public String toString() {
        return name + " has a " + car.toString();
    }
    public static void main(String[] args) {
        // 1st
        User u = new User() {
            { // my problem is here : is this block OK?
                setName("Tom");
                setCar(new Car(1, "Volvo"));
            }
        };
        // 2nd or this
        // Car car = new Car(1, "Volvo");
        // User u = new User();
        // u.setName("Tom");
        // u.setCar(car);

        System.out.println(u);
    }
}

I know this works fine in C#, and it seems that it also works in Java. However, it's really not clear that if that's right or a good code style... Really thanks for your help!

Little Helper
  • 1,870
  • 3
  • 12
  • 20
SteveHu
  • 82
  • 9
  • 1
    What style works for you is personal. I tend not to do this, and I know others find this confusion, but this could be fine. – Peter Lawrey Jul 26 '18 at 09:15
  • Pretty opinion-based, isn´t it? Voting to close. – MakePeaceGreatAgain Jul 26 '18 at 09:17
  • @HimBromBeere Not really. Sometimes opinions are just de facto standards. – GhostCat Jul 26 '18 at 09:17
  • @GhostCat Even if such a de-facto standard *would* exist (which was new to me, anyway), there might allways be good reasons to break them. So there simply is no generel rule and it highly depends on what OP wants to achieve. Sometimes it even depends on external factors such as company-standards that might contradict what you consider a de-facto. – MakePeaceGreatAgain Jul 26 '18 at 09:20
  • @HimBromBeere in this case, there are some relevant technical differences between the two approaches - the results differ, and it seems that the OP is not aware of this difference. – Hulk Jul 26 '18 at 09:33

2 Answers2

3

In Java, you are creating an anonymous inner class here.

So that object is not a User, but a subclass of User.

It is pretty uncommon, and most people consider it bad style. Some people use it "by accident" (not knowing what they are doing), a few suggest to follow this pattern. But in general, it will surprise most of your readers, and a base rule in programming is to avoid doing that. You follow conventions, even when they are informal and not written down.

And for the record: depending on how you implemented your own equals() method, this approach of creating sub class instances on the fly might even lead to bizarre bugs.

Therefore: simply don't do it.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 1
    Thanks! And you're right. I tried to print 2 objects created in 2 different ways with method `getClass()`, and they're totally different classes. I had thought this is just an anonymous code block with calling some methods, but apparently it's not that easy! – SteveHu Jul 26 '18 at 09:39
  • @SteveHu That was quick. And welcome to upvote land ... if you want to practice ... feel free to start here ;-) – GhostCat Jul 26 '18 at 12:50
1

In c# there is a construct called Object Initializer and it looks syntactically similar to what you tried to do here.

However, this does not exist in Java.

What you proposed is a combination of an Anonymous Class Declaration and an Instance Initializer that is sometimes refererred to as "Double Brace Initialization" and comes with several serious caveats - see this question for even more reasons to avoid this in addition to the valid points GhostCat mentioned in his answer.

Hulk
  • 6,399
  • 1
  • 30
  • 52
  • A good answer in which I got what this code is. I think now it's much clearer for me, thanks for your answer! – SteveHu Jul 26 '18 at 11:22