Anon
Anon

Reputation: 341

JavaScript-like Object data type in Java?

I am experienced in JavaScript, but new to Java. In JavaScript there are "object" data types where a given variable essentially has sub-variables with their own unique values, for example:

var car = {type:"Fiat", model:500, color:"white"};

It is almost like an array, but not quite (JavaScript has arrays too). I am wondering if the same type of thing exists in Java? If so, how would I declare the same thing in Java? Based on my searches I can't find an object data type, but thought maybe there was something similar?

Upvotes: 31

Views: 26396

Answers (4)

Alex Melnikov
Alex Melnikov

Reputation: 19

If you want some JS-syntax in JVM you can try to use Groovy instead of Java

Upvotes: -1

degr
degr

Reputation: 1565

Most nice object for this purpose it's a LinkedHashMap. You can use it like map, but on iteration it will keep keys order.

Upvotes: 1

ssube
ssube

Reputation: 48307

While Java has a type called object, it's not what you want. Almost everything in Java is an object, and there are two ways to handle this:

  1. Define a strongly-typed object with the correct properties, as a class. Javascript has a similar concept, implemented differently, but it should be recognizable:

    public class Car {
        private String type;
        private int model;
        private String color;
    
        public Car(final String type, final int model, final String color) {
            this.type = type;
            this.model = model;
            this.color = color;
        }
    
        public String getType() { return this.type; }
        public int getModel() { return this.model; }
        public String getColor() { return this.color; }
    }
    
    final Car car = new Car("Fiat", 500, "white");
    
    // To get the color, you must:
    car.getColor();
    

    Add methods to get and set attributes as appropriate, methods to start, stop, drive, etc.

  2. If you want a loose collection of properties without behavior or restriction, use a Map. Again, there exists a Javascript equivalent (the {x: 1, y: 2} construct without using the new keyword).

    final Map<String, Object> car = new HashMap<>();
    car.put("type", "Fiat");
    car.put("model", 500);
    car.put("color", "white");
    
    // To get the color, you:
    car.get("color");
    

    The disadvantage with this approach is that the compiler cannot enforce the types of those objects (nearly as well), and the map cannot have custom behaviors (in any reasonable way). In your example, model was a number, but this will allow you to assign anything regardless of whether it makes sense (perhaps someone keeps the data on a server and uses an HttpConnection, all of your code expecting a number explodes).

In Java, the first method is recommended if you know you'll have multiple cars, all with the same (or similar) properties. It allows the compiler to both enforce and optimize for the properties that you know will exist, and inheritance allows you to add additional properties later. The class also allow you to define methods which operate on that instance, which can help create abstraction between parts of the system (you don't need to know how a car starts, you just tell the car to start itself).

For reference, the Javascript equivalents are:

// #1
var Car = function(type, model, color) {
    this.type = type;
    this.model = model;
    this.color = color;
}

var car = new Car("Fiat", 500, "white");

// #2
var car = {type: "Fiat", model: 500, color: "white"};

// For either option, to get the color you can simply:
console.log(car.color);

What should stand out most obviously is that Java keeps track of what type each variable is. Not visible is that Java will prevent you from assigning to unknown properties, say car.mileage, where Javascript will happily add a new property. Finally, Java has a concept of visibility, and makes things private (invisible to outside viewers) by default. Replicating that in Javascript would look something like:

var Car = function(type, model, color) {
    var _type = type;
    var _model = model;
    var _color = color;

    this.getType = function() { return _type; }
    this.getModel = function() { return _model; }
    this.getColor = function() { return _color; }
}

console.log(car.getColor());

In Javascript, you take advantage of closure to hide data. Java defaults to hidden, and requires you to expose data when you need to. It's an interesting choice, very relevant when comparing code-bases, and can help keep classes independent of one another. It's also very easy (and tempting) to violate when you start writing in OO languages, so something to keep in mind (using simple structs will come back to haunt you).

Upvotes: 37

Ross Drew
Ross Drew

Reputation: 8246

Yes, they are called Objects and defined by Classes. It's basically the first thing you learn when learning Java

//The definition of an object and it's members
public class Car { 
 String type, model, color;
}

You can then make them public to access and change them external to the class

public class Car {
 public String type, model, color;
}

And access them like so

//Create an instance of a Car, point to it with variable c and set one of it's properties/members
 Car c = new Car();
 c.type = "Fiesta";

But allowing variables of a class to be edited externally is considered bad form in Java, generally you would add methods to access each, called accessors

public class Car {
  private String type, model, color;

//Return the type of this object
  public String getType(){
    return type;
  }

//Set the type of this object
  public void setType(String type){
    this.type = type;
  }

  //etc
}

Then access them like so

 Car c = new Car();
 c.setType("Fiesta");

A class is the template you write to create objects, which are run time instances of classes.

Upvotes: 2

Related Questions