I was wondering what the best way of documenting this potential Point class is:
public class Point {
/* the X coordinate of this point */
private int x;
/* the Y coordinate of this point */
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
My concrete concern lies with the repetition between the x and y attributes and their respective getters and setters, as well with the constructor arguments.
It's not that I'm developing a public API or anything of the likes, it's no problem for me to have a general comment regarding some variable and then having the getter and setter have just the same text, for instance. I'd just like to avoid comment repetition in my own internal code. Is there a way to tie getX() and the int x argument of the constructor to the x attribute, for instance?
Thanks
Is there a way to tie getX() and the int x argument of the constructor
to the x attribute, for instance?
No, not that I'm aware of. What I do:
don't comment getters (or setters) at all
if X needs contextual information and if it somehow represents (part of the) state of the class I document it in the class-level Javadoc only
One obvious convention would be not writing JavaDoc comments for trivial getters.
Related
I need to write a vector class that accept any primitive number types in Java.
My vector class should only accept 2 components. Here is where I am having trouble.
I must write a function that adds two vectors and return a completely new vector.
If anyone knows a solution of allowing my vector class to accepts in primitive types and perform vector operations like Python, please point me in the right direction!
Something like in pseudocode:
AddVectors( V1, V2):
return new Vector( V1.getX + V2.getX, V1.getY + V2.getY)
Here is my some snipped code of my vector class:
public class Vector<T> {
private T x;
private T y;
public Vector(T x, T y){
this.x = x;
this.y = y;
}
public T getX(){
return x;
}
public T getY(){
return y;
}
}
Consider this:
public class Test {
public static int numberOfInstances = 0;
public int myInstanceID;
public String myInstanceName;
The static variable doesn't need to be called within an instance, it's available everywhere like this:
Test.numberOfInstances
When creating an instance, I only do this into my constructor:
public Test(int id, String name) {
myInstanceID = id;
myInstanceName = name;
numberOfInstances += 1;
}
I've recently discovered the this keyword and have noted some of its uses:
public Test() {
this(numberOfInstances + 1, "newInstance");
numberOfInstances += 1;
}
From what I've noticed, the this keyword allows you to call another one of the class' constructors. It also allows you to do this:
public Test(int x, int y) {
this.x = x;
this.y = y;
}
With java, I highly disagree with this style; same variable names, and I don't see the point of using this, especially after looking at the docs example. I look at this:
public Test(int a, int b) {
x = a;
y = b;
However, the use of the this keyword isn't necessary; In my code, I have a variables in my class (e.g. xCoordinate) where I don't use the this keyword (it's not static).
What I've been struggling to understand is what the difference is between non-static variables and this variables. Is there a difference? In one of my classes (the Paddle for Pong), I have this:
public class Pong {
public int xCoordinate;
public int yCoordinate;
and so on...
I never use the this keyword anywhere, and the data is stored within it's own instance.
Bottom line, my question is what is the difference between non-static variables and this.variables. Is it a standard coding practice? Why would I ever you the this keyword on non-static variables?
I think you may have almost answered your own question. You provided the function
public Test(int x, int y) {
this.x = x;
this.y = y;
}
However, what do you think would happen if you wrote it this way instead?
public Test(int x, int y) {
x = x;
y = y;
}
Noticed that I removed the this in the second function. Therefore, x and y would just be referring to the local x and y variables. this allows you to specify that you actually want to use the non-static class variables x and y.
If, as is typical, the parameter variable names of a constructor (say x) are the same as fields of the class, then the field names are shadowed by the parameters passed.
this is used in this case to disambiguate: this.x denotes the field x. It makes perfect sense. this means "reference to the current instance".
So, statements like this.x = x; are quite common.
If you still continue to dislike the Java style, and you adopt m_x-style notation for class fields, then you can write m_x = x; in your constructor. As you rightly point out, this is then not required.
this is also used as the notation for delegating constructors, as you point out.
The "this" keyword allows you to difference between method and instance variables:
public class Point {
private int x;
private int y;
public void add(int x, int y) {
this.x += x;
this.y += y;
}
}
There is no this variables. It's just used to tell the compiler that the variable you want to change is the declared field and not the local variable, in case they have the same name.
For the constructor part, this is just a shortcut for classes which have multiple constructors. You can write the code once and just call that from the alternative constructors.
There is also a similiarly used keyword super, which allows you to call methods and constructors of the superclass:
public SomeClass(int x) {
super(x);
super.someMethod(); // even if we would have overridden someMethod(),
// this will call the one from the superclass
}
Here's one instance where you would need the 'this' keyword:
public class Pong {
public int xCoordinate;
public int yCoordinate;
public Pong (int xCoordinate, int yCoordinate) {
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
}
}
public class Point {
private double x;
private double y;
Point (double x, double y)
{ this.x = x; this.y = y; }
double getX() { return x; }
double getY() { return y; } }
Are the objects in the above class immutable? Explain.
I am getting confused because
There r no setters so nothing can modify the objects
BUT
there is no final variable or final class which it should contain.
If the class gets extended, it could add extra fields that are not immutable, or the methods could be overridden to return a different value each time. Doesnt this make the class not immutable?
If the class gets extended, ... the methods could be overridden to return a different value each time. Doesn't this make the class not immutable?
Your question is subtle. If some class MutPoint extends Point and overrides the getX() and getY() methods to return non-constant values, that doesn't change the Point class itself. Instances of Point sill will be effectively immutable, but a caller would be allowed to pass MutPoint objects to your methods that expect Point arguments. What happens then? Depends on how you write your code. It could be that your code would behave badly if the caller gave you a Point-like object, and then subsequently changed its "value".
If your code that uses Point objects requires them to never change, then you might want to declare the whole class final
public final class Point { ... }
That way, your client will not be allowed to override the class, and will not be allowed to call your methods with anything other than an actual Point instance.
Yes, they are immutable. You can read about it here
http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
Yes, because you can't accsess to the data member and you don't have method that change your data members
I'm writing a program that will need to use a limited set of Points to process an image. I figure that I would implement it as an immutable/singleton style class. Before going on to build more of the complex logic surrounding the class I wanted to get an opinion about the core class.
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.HashMap;
public class Point {
private final int x,y;
private final int hashCode;
private static final HashMap<int[],Point> points = new HashMap<>();
private Point(int x,int y){
this.x = x;
this.y = y;
this.hashCode = new HashCodeBuilder().append(x).append(y).toHashCode();
}
public static Point getPoint(int x,int y){
int [] candidate = new int[]{x,y};
if(points.containsKey((candidate))){
return points.get(candidate);
}
Point newPoint = new Point(x,y);
points.put(candidate, newPoint);
return newPoint;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public int hashCode(){
return hashCode;
}
#Override
public boolean equals(Object p){
return this == p;
}
}
I'm going to be using the class to do at least the following functions:
Map different channels in an image by this Point class
Define some static cached custom NavigableSets for ease of traversal
Various Helper functions. In example, get all Points surrounding a Point
Given the information provided, what are some downsides of the provided implementation?
Note: Putting the bulleted list before the code block breaks the display of the code block. Bug?
I think your caching "singletony" stuff may be pointless.
It doesn't save on object creation, as you will always create a candidate[] each time you ask for a Point. And, unless the Point gets reused, you use the memory for candidate and the Map.Entry in your HashMap. So, very roughly speaking, unless each Point gets reused three times, your caching uses more memory. And it always uses a more time.
If you don't cache, change your equals of course.
p.s. the rest seems fine, and immutable is good. You could consider making x and y public final to be more compatible with other Point implementations.
If you are worried about the occupied memory, there is another way to deal with it.
I assuming you have limited dimension for your points, I would suggest to combine your x & y in one variable of long (in case your dimensions is 32 ints long), or even int (if you can fit one dimensions in 16 bit), this way you'll get boost in performance & memory.
Other option is to use int[] array of your coordinates for a point, although that would take more space (since you would have to keep additional pointer reference).
Factory method in your implementation, will work only on single threaded applications, if you have multiple threads creating points, you would need to have some concurrency control in place. This would eat up your resources, because you would effectively need to lock on each point creation.
Another reason, why this Factory method is a bad idea, is that int[] arrays do not override equals and hashCode, you can try to create 2 arrays with same content, to check. So your HashMap would not simply work, and instead of saving memory you would not only create a new Point each time, but also add an entry to your HashMap and perform unnecessary calculations.
So either use Java primitives, or just create a new immutable Point each time if you need too, and go with it, don't overcomplicate with factoryMethods.
You had the right idea of making the Point class immutable but then you went and complicated things with the instance cache. It is not thread safe and it will leak memory because once a Point is created it will forever stay in the hashmap and will never be garbage collected.
Why not keep it simple and make a regular boring value class? Your IDE will even generate it for you.
Then, if you really really really want to have an instance cache, use Guava's Interner class instead of rolling your own. The result will look something like this:
public class Point {
final int x;
final int y;
private Point(int x, int y) {
this.x = x;
this.y = y;
}
static Interner<Point> instanceCache = Interners.newWeakInterner();
public static Point of(int x, int y) {
return instanceCache.intern(new Point(x,y));
}
public int getX() { return x; }
public int getY() { return y; }
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point other = (Point) o;
return this.x == other.x && this.y == other.y;
}
#Override
public int hashCode() { return x * 31 + y; }
}
Suppose I have class with 2 fields: x and y, of type double. Is it possible to define 2 constructors so constructor1 will create object setting its x property to what parameter in constructor tell and y to default and constructor2 vice versa?
public class Test {
private int x;
private int y;
public Test(int x) {
this.x = x;
}
public Test(int y) {
this.y = y;
}
}
I'm trying something like that and I know that it wont work because of overloading rules
No, you can't do that. Typically you'd do something like:
private Test(int x, int y) {
this.x = x;
this.y = y;
}
public static Test fromX(int x) {
return new Test(x, 0);
}
public static Test fromY(int y) {
return new Test(0, y);
}
You might want to consider that pattern (public static factory methods which in turn call private constructors) even when you don't have overloading issues - it makes it clear what the meaning of the value you're passing is meant to be.
No, You cannot have two methods or constructors with the same signature. What you can do is have named static factories.
public class Test {
private int x;
private int y;
private Test(int x, int y) {
this.x = x;
this.y = y;
}
public static Test x(int x) { return new Test(x, 0); }
public static Test y(int y) { return new Test(0, y); }
}
Test x1 = Test.x(1);
Test y2 = Test.y(2);
No, x and y have identical types, so both constructors would have the same type signature and the method resolution is based on parameter type, not name; the compiler has no way of differentiation.
The compiler looks for "Test.Test(int)" regardless of what the name of the parameter is.
The language would need additional feature added, such as named parameters, to do what you want.
If Java ever gets a syntax like C# for property initialization, you'll be able to use that idiom, using a default no-args constructor.
Besides the alternatives of using explicit factory methods, you could pass in a HashMap for your parameters.
public Test(HashMap<string,int> args) {
if(args.containsKey("x"))
x = args.get("x");
if(args.containsKey("y"))
y = args.get("y");
}
But static factory methods are cleaner for most cases. If you need much more, you may need to consider why you need such an idiom in the first place, and revise your class design.