Looks to me like primitive classes could behave more efficiently (at reasonable sizes) if they weren't immutable as currently proposed, but worked more like C structs.
Given this primitive class
primitive class Point implements Shape {
public long x;
public long y;
public Point(long x, long y) {
this.x = x;
this.y = y;
}
public boolean contains(Point p) {
return equals(p);
}
}
interface Shape {
boolean contains(Point p);
}
And an array Point[] points = new Point[N];
Why wouldn't we be able to do this?
points[0].x = 42; //lastore
points[1].x++; //laload, iinc, lastore
Point p = points[2]; //laload, laload
Shape s = p; //new Point.ref (boxing)
p.x++; //iinc
assert !s.contains(p);
Instead it sounds like current design intends for the whole Point be read, mutated using withfield and written back in its entirety, which seems kind of wasteful - especially for larger types. Or would compilers routinely apply copy elision here?
Note that Point must be flattened instead of flattenable here, so the user can be certain not to mutate a shared instance.
Could someone further clarify the rationale behind immutability of primitive types?
#see
JEP 401: Primitive Classes (Preview)
State of Valhalla - Part 3: The JVM Model
Related
I have two questions
Say I have some structure in jni say
struct X
{
Type_A x;
Type_B y;
}
Now how do I?
Pass this structure as an argument to a java call back function
How do I return this structure to a Java function.
If possible, please give an example.
Java Native Access handles the details automatically (in addition to avoiding the native compilation step entirely).
public class MyStructure extends com.sun.jna.Structure {
public int x;
public int y;
}
It also supports nested types, so you can have structures, pointers, or even unions as fields within the structure.
If you pass a data structure to Java, this must be a Java object. You can either create it on the JNI side, or fill in a parameter object passed to JNI by Java. (E.g. Java can create a new byte[4096] and pass it to a JNI function to store the result there.)
BUT sometimes you want Java to store pointers to native structures. You cast such pointer to an int/long and pass it to Java. No Java garbage collector would free such memory, you have to do that explicitly (as in C). In addition, you will need to call a JNI function to free such memory. You could play with finalize(), but I'd recommend explicit deallocation at predictable times from predictable threads(!).
I think I finally figured this out there are two approaches
Create an object in java --> send it to the native code --> fill it
Create an object in the native code --> return it back
I have done it in both these approaches and it works like a charm
If there is a better approach please do let me know....
What worries me is how does garbage collection function for an object created in the native side ???? If you have an answer please do comment below
And if anyone is facing a similar problem comment below so that I can post the code...
You should use a object to represent the struct. the object could be something like this:
public class Struct {
private Type_A x;
private Type_B y;
public Struct(Type_A x, Type_B y) {
this.x = x;
this.y = y;
}
public Type_A getX() {
return x;
}
public void setX(Type_A x) {
this.x = x;
}
public Type_B getY() {
return y;
}
public void setY(Type_B y) {
this.y = y;
}
}
To use, you can invoque a function like this:
myFunction(new Struct(x,y));
and the function return the object like this:
public Struct myFunction(Struct struct){
....
return struct;
}
Hope it helps you!!
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
Consider we have two class named Point and Line. And Line class has two constructors. This is code of Point class.
// The Point class definition
public class Point {
// Private member variables
private int x, y; // (x, y) co-ordinates
// Constructors
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point() { // default (no-arg) constructor
x = 0;
y = 0;
}
}
And this is code of Line class.
public class Line {
// Private member variables
Point begin, end; // Declare begin and end as instances of Point
// Constructors
public Line(int x1, int y1, int x2, int y2) {
begin = new Point(x1, y1);
end = new Point(x2, y2);
}`
public Line(Point begin, Point end) {
this.begin = begin;
this.end = end;
}
}
As you see Line class has two constructor. And First constructor is example of Compositon while second constructor example aggregation. Now, what can we say about this case? Can a class have both aggregation and composition? Thank for your answers.
A generally accepted definition of the difference between aggregation and composition is lifetime responsibility and ownership.
Aggregation: An object A holds references to other objects, but those other objects are shared with other classes. When A is disposed, the other objects continue to live and be used in the application
Composition: An object B is "made" of other objects. When A is disposed, so are the other objects.
It's worth quoting Fowler on this:
Few things in the UML cause more consternation than aggregation and composition
...
Aggregation (white diamond) has no semantics beyond that of a regular association. It is, as Jim Rumbaugh puts it, a modeling placebo
...
Composition (black diamond) does carry semantics. The most particular is that an object can only be the part of one composition relationship
So yes, a class can have both composition and aggregation relationships to the objects it holds references to, but possibly not as per the example you have shown.
Since the defining characteristic of composition (versus aggregation) is having exclusive/non-shareable parts (see https://stackoverflow.com/a/27889087/2795909), your example of a Point-Line part-whole relationship is clearly an aggregation (no matter if you pass the point objects to, or create them in, the constructor) since the two points definijng a line can be shared with other lines.
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; }
}
I'm creating a Vector2 class in Java, and have an issue:
public class Vector2 {
public static final Vector2 ZERO = new Vector2(0,0);
...
}
in another class, I'd like to call ZERO like this:
Vector2 myVector = Vector2.ZERO; //initialize to zero
myVector.add(myOtherVector); //myVector is now the sum of Vector2.ZERO and myOtherVector
However, this behaves undesirably: myVector just becomes Vector2.ZERO--and thus unchangeable--rather than being initialized to the zero value and then being free to work with as I wish. To get the behavior I want, I need:
Vector2 myVector = new Vector2(Vector2.Zero); //initialize to zero with copy constructor
I'm a little confused by Java's semantics here (i.e someVector essentially seems to be a pointer rather than an actual object, so I have to create a new object and explicity copy the values.) After reading up on that, I understand there's a lot of confusion on that topic. Is there a simple way to achieve the syntax I'm looking for or should I just stick with option 2? If there isn't, is there a way to prevent the assignment in option 1? It's going to give me some hard to catch errors later if I don't stop it at compile time.
Edit: Vector2 isn't immutable. What I'd like is for Vector2.ZERO to be a constant value I can use for assignments, but then manipulate those new variables normally. Right now if I do that assignment in multiple places, then all of those are just pointers to the same object (which because it's static just accumulates the changes).
For example, in Unity when working with vectors I would say something like:
Vector2 myFirstVector = Vector2.ZERO; //first vector, initialized to zero
...//do some stuff to change the value of myFirstVector, Vector2.ZERO unchanged
Vector2 mySecondVector = Vector2.ZERO; //second vector, also initialized to zero
...//do some stuff to mySecondVector
If you want your vectors to be mutable, having a static field that holds the zero vector is not a good choice (since it can mutate to something else later.
There are two approaches that you can take:
Mutable Vectors
public class Vector2 {
public static Vector2 Zero() {
return new Vector2(0,0);
}
}
Immutable vectors
public class Vector2 {
public static final Vector2 ZERO = new Vector2(0, 0);
private final int x;
private final int y;
public Vector2(int x, int y) {
this.x = x;
this.y = y;
}
public Vector2 add(Vector2 v) {
return new Vector2(this.x + v.x, this.y +v.y);
}
}
You may want to create a static factory method to return a new Vector that is Zeroed.
public class Vector2 {
public static Vector2 Zero() {
return new Vector2(0,0);
}
}
Then use it:
Vector2 myVector = Vector2.Zero();
Of course, if your default constructor initializes the vector to 0,0, then you may not need this and can simply do: Vector2 myVector = new Vector2();
Your initial thought about: "However, this behaves undesirably: myVector just becomes Vector2.ZERO--and thus unchangeable--" is incorrect unless Vector2 is immutable. You won't be able to reassign anything else to Vector2.ZERO, but you can certainly modify the object's contents.
Make your class immutable, so add() would return a new instance rather than modifying the instance, then:
myInstance = myInstance.add(myOtherVector);
See BigInteger for a class from the JDK that works like this.
That is the whole point of OOP and object references.
Vector2 myVector = Vector2.ZERO;
means that your myVector variable will reference to the same object (in memory) as static field Vector2.ZERO does. Basicly it is reffering the same object in memory.
You wrote:
someVector essentially seems to be a pointer
well, that is preatty it. References can be understood as pointers to objects just as pointers to defined memory address in C.