Structs have their place, even in Java. You should only use them if the following two things are true:

 - You just need to aggregate data that doesn't have any behavior, e.g. to pass as a parameter
 - It doesn't matter one bit what sort of values that aggregate data has

If this is the case then you should make the fields public and skip the getters/setters. However, if either one of those do not apply, you should use a class and make the fields private.

To check if your supposed-struct has behavior, look at when the fields are used. If it seems to violate [tell, don't ask](http://pragprog.com/articles/tell-dont-ask), then you need to move that behavior into your class.

If some of your data shouldn't change, then you need to make all those fields private and final and use only getters to access them. You might consider making your class [immutable](http://www.javaranch.com/journal/2003/04/immutable.htm). If you need to validate your data, then make the fields private and provide validation in the setters and constructors.

Your Bottle example would most likely fail both tests. You could have (contrived) code that looks like this:

 public double calculateVolumeAsCylinder(Bottle bottle) {
 return bottle.height * (bottle.diameter / 2.0) * Math.PI);
 }

Instead it should be

 double volume = bottle.calculateVolumeAsCylinder();

If you changed the height and diameter, would it be the same bottle? Probably not. Those should be final. Is a negative value ok for the diameter? Must your Bottle be taller than it is wide? Can the Cap be null? No? How are you validating this? Assume the client is either stupid or evil. You need to check these values.

This is what your new Bottle class might look like:

 public class Bottle {
 
 private final int height, diameter;
 
 private Cap capType;
 
 public Bottle(final int height, final int diameter, final Cap capType) {
 if (diameter < 1) throw new IllegalArgumentException("diameter must be positive");
 if (height < diameter) throw new IllegalArgumentException("bottle must be taller than its diameter");

 setCapType(capType);
 this.height = height;
 this.diameter = diameter;
 }
 
 public double getVolumeAsCylinder() {
 return height * (diameter / 2.0) * Math.PI;
 }
 
 public void setCapType(final Cap capType) {
 if (capType == null) throw new NullPointerException("capType cannot be null");
 this.capType = capType;
 }
 
 // potentially more methods...
 
 }