Java Static Class Variable Initialisation Efficiency - java

I have the following:
public class ExampleObject extends GridObject {
private static Context c;
private static final String name = "Example Object";
private static Bitmap skin = BitmapFactory.decodeResource(c.getResources(), R.drawable.defaultObject );
private static float x,y;
public ExampleObject(Context c, float x, float y) {
this.c = c;
this.x = x;
this.y = y;
}
}
The class has 3 static class members, The image is a decoded bitmap, I want it to be decoded once and once only for use on ALL instances of this object.
In it's current state is this achieved? or is it decoded every time an instance of this class is created?
How should it be done?

A static field will only be initialized once; this is guaranteed by the JLS.
However, the decodeResource method will be called when the class is initialized, at which point your Context is null, so it will fail. You'll need something more complex if you want a static field which is only initialized once; something a bit closer to a singleton.
public class ExampleObject extends GridObject {
private static final String name = "Example Object";
private static Bitmap skin;
// = BitmapFactory.decodeResource(c.getResources(), R.drawable.defaultObject );
private static float x,y;
public ExampleObject(Context c, float x, float y) {
synchronized(ExampleObject.class) {
if(skin == null) {
skin = BitmapFactory.decodeResource(c.getResources(), R.drawable.defaultObject);
}
}
this.x = x;
this.y = y;
}
}

You can achieve your intended behavior by the following class definition.
public class ExampleObject extends GridObject {
private static Bitmap skin;
public static Bitmap getSkin(Context c){
if(skin == null){
skin = BitmapFactory.decodeResource( c.getResources(), R.drawable.defaultObject );
}
return skin;
}
}

Static variables are initialized only once and A single copy of it is to be shared by all instances of the class.
This single initialization procedure is run automatically, one time only, when the class is first loaded.
You may want to use "static block" to initialize your classes's static fields.
For example:
// start of static block
static {
//initialize your static fields
System.out.println("static block called ");
}
// end of static block

Related

Call Super-Constructor multiple times

In my current programming project I have some basic classes, like Numbers or ImageSets. In other classes I use these to display Information. I thought the easiest way (not so much coding) is to let the Display-Classes extend the base-Classes.
But at one Class (TwoDigits) I need two instances of the superclass (ImageSet). Is this possible? Normally you would call super(), but a second super() call is not allowed...
Here is some code of the Number-Class: (Element is another abstract selfmade class)
public class ImageSet extends Element{
private int x;
private int y;
private int imageIndex;
private int imagesCount;
public ImageSet(int x,int y,int imageIndex,int imagesCount, boolean ignoreDimension) throws IOException, UnequalDimensionsException {
if(!ignoreDimension) {
[...]//Check for equal Dimensions, otherwise throw UnequalDimensionsException
}
this.x=x;
this.y=y;
this.imageIndex=imageIndex;
this.imagesCount=imagesCount;
}
[...]
}
Here is some code from the Base-Class (TwoDigits):
public class TwoDigits extends Element{
ImageSet tens;
ImageSet ones;
Dimension d = null;
public TwoDigits(int x, int y, int imageIndex, int imageCount, boolean ignoreDimension) throws UnequalDimensionsException, IOException{
tens = new ImageSet(x,y,imageIndex,imageCount,ignoreDimension);
String imageIndexFormatted = String.format("%04d", imageIndex);
d = StaticHelpers.getImageDimension(new File("data/"+imageIndexFormatted+".png"));
ones = new ImageSet(x+d.width,y,imageIndex,imageCount,ignoreDimension);
}
[...]
}
I would like to change the SuperClass of TwoDigits to ImageSet to save some code in other classes.
Thanks for any help.

Referring a class on a list newbie confusion

I was studying livewallpaper in this site. However something there is something that i dont understand.
Example in the code of the tutorial there a class named MyPoint
public class MyPoint {
String text;
private int x;
private int y;
public MyPoint(String text, int x, int y) {
this.text = text;
this.x = x;
this.y = y;
}
}
then after he created a MyWallpaperService class. Inside of that class there is a line of code like this
private List<MyPoint> circles;
private Paint paint = new Paint();
private int width;
int height;
private boolean visible = true;
private int maxNumber;
private boolean touchEnabled;
public MyWallpaperEngine() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(MyWallpaperService.this);
maxNumber = Integer
.valueOf(prefs.getString("numberOfCircles", "4"));
touchEnabled = prefs.getBoolean("touch", false);
circles = new ArrayList<MyPoint>();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(10f);
handler.post(drawRunner);
}
You can see the part of code has
private List<MyPoint> circles;
This is the part that i dont understand? What is happening in here? What will List<MyPoint> pass in the circles? Anyone knows what to call this? is this list reffering to a class? Cause im not sure on my title. Thank you..
private List<MyPoint> circles;
States that circles is a List of type MyPoint, (ie. it will hold objects of type MyPoint).
circles = new ArrayList<MyPoint>();
Now in the above line you are assigning the ArrayList object of type MyPoint to the Object Reference Variable of type List.
This is called as Interface Polymorphism.
List is an Interface, where as ArrayList a Concrete Class which implements List.
Eg:
public class Dog{
private String dName;
priavet int dAge;
public Dog(String dName, String dAge){
this.dName = dName;
this.dAge = dAge;
}
public String getDName(){
return this.dName;
}
public String getDName(){
return this.dAge;
}
}
public class Test{
public static void main(String[] args){
List<Dog> dAList = new ArrayList<Dog>();
dAList.add(new Dog("Tommy",5));
dAList.add(new Dog("Stark",2));
for(Dog d : dAList){ // Iterating over the List of Dog objects
System.out.println(d.getDName());
System.out.println(d.getDAge());
}
}
}
The List<MyPoint> object is, as the name suggests, a list of MyPoint instances which, judging from the code, represent the centers of your circles. The private identifier simply indicates that it cannot be accessed from outside of the class in which it is defined.
Its creating a list of objects. A List of MyPoint type objects
MyPoints in your case refers to the (x,y) coordinates of the circle(as you referred)

Out of order chained constructors

public class ParentClass
{
public ParentClass(int param);
}
public class MyClass extends ParentClass
{
private int _a;
private int _b;
private int _c;
public MyClass(String input)
{
_a=CalculateA(input);
_b=CalculateB(_a);
_c=CalculateC(_a);
super(_b+_c);
}
//a expensive procedure
private int CalculateA(String text);
private int CalculateB(int a);
private int CalculateC(int a);
}
Java doesn't allow chained constructors to be anything other than the first method put in a constructor.
Chained constructors can't call nonstatic methods as arguments (which removes the possibility of using Initialsers that return the value they initialize to).
How do I achieve the above code using legal Java?
Edit Indeed Java does not allow a constructor to do any calculations before the call to a parent's class constructor, even if these involve only static methods (as your calculateX's should be) and results only assigned to variables that are private to the class (like your _a, _b and _c) or local to the constructor.
There is a way around this, however: call another constructor with the result of the calculateX call assigned to its parameter - then you can access this result throughout the other constructor.
public class MyClass extends ParentClass {
private int _a,_b,_c;
public MyClass(String input) {
this(calculateA(input));
}
private MyClass(int a) {
this(a, calculateB(a), calculateC(a));
}
private MyClass(int a, int b, int c) {
super(b + c);
this._a = a;
this._b = b;
this._c = c;
}
private static int calculateA(String text) {
try {Thread.sleep(1000);} catch (Exception e) {} // expensive ;-)
return text.length();
}
private static int calculateB(int a) { /* ... */ }
private static int calculateC(int a) { /* ... */ }
}
Edit 2 With more calculations or more intermediate results to store for later use, this approach would lead to an even longer chain of constructors consisting only of this(...)-calls. A more fancy solution with only two constructors, the public one and one private, is possible with a helper class (reasonably an inner class):
public MyClass(String input) {
this(new InitCalcResult(input));
}
private MyClass(InitCalcResult initCalcResult) {
super(initCalcResult.initB + initCalcResult.initC);
this._a = initCalcResult.initA;
this._b = initCalcResult.initB;
this._c = initCalcResult.initC;
}
private static class InitCalcResult {
private int initA, initB, initC;
InitCalcResult(String input) {
initA = calculateA(input);
initB = calculateB(initA);
initC = calculateC(initA);
}
}
(using the same private fields and static calculateX methods as above).
You can do something like this.
public abstract class ParentClass
{
public ParentClass(String input){
int a = getData(input);
/* Do what ever u need to do with a*/
};
public abstract int getData(String input);
}
public class MyClass extends ParentClass
{
private int _a;
private int _b;
private int _c;
public MyClass(String input)
{
super(input);
}
public int getData(String input){
_a=CalculateA(input);
_b=CalculateB(_a);
_c=CalculateC(_a);
return _b+_c;
}
//a expensive procedure
private int CalculateA(String text){/* return int */};
private int CalculateB(int a){/* return int */};
private int CalculateC(int a){/* return int */};
}
Since getData is abstract, the base class function will get called. And the super class will get the required data.

'this' prefix in Java?

Does the this prefix for accessing member variables exist in Java?
Here is my HelloWorld code:
public class HelloWorld {
public static int x = 0;
public static void main(String[] args) {
HelloWorld.x = 45;
System.out.println(HelloWorld.x);
}
}
The above code works with/without the class name prefixing the variable x. However, if i try: this.x = 45; or this->x = 45; I receive an error:
non-static variable this cannot be referenced from a static context
I understand member variables can be accessed without the HelloWorld (class name) prefix, like I have done. But, I want to know if the this prefix exists in Java, how do I use it?
EDIT:
Also, could you provide an example where this is appropriate?
duffymo & byte - I greatly appreciate your help. Thanks.
Java has this as a prefix, but it's a reference to the current instance.
Static methods and attributes are associated with a class, not an instance, so you can't use this inside a static method.
public class HelloWorld {
public int x = 0; // note: now it's an instance attribute
public static void main(String[] args) {
HelloWorld hw = new HelloWorld();
System.out.println(hw.x);
}
public int getX() { return this.x; }
public void setX(int x) { this.x = x; }
}
You're attempting to use 'this' to refer to a static, not an instance variable. 'this' is only used to refer to the instance variables of an instantiated object of this class. You cannot use 'this' to refer to static variables on a class.
When you use 'this' you are saying "I want to refer to the variables of this particular instantiation of this class". A static on the other hand is always going to be the same variable for the class, irrespective of instantiation.
In addition the correct syntax for referring to an instance variable is by the dot operator:
this.x = 42; //correct
this->x = 42; //will not compile as its not valid Java
So essentially what you're after is something like the following:
public class Foo {
private int x;
public void setX(int x) {
this.x = x;
}
public int getX() {
return this.x;
}
}
public class HelloWorld {
public static void main(String[] args)
{
Foo foo = new Foo();
foo.setX(45);
System.out.println(foo.getX());
}
}
Remove the static modifier from your variable and then try it with this. Here is the difference:
Static variables exist only once in the whole program. No matter where you are, you could refer to HelloWorld.x and it would always be the same thing. That means, as you've declared it, anyone can modify it too, which may or may not be a good thing.
Member variables (not declared with static) are local to an instance of a class, which means you have to have created an instance with new before you can use it. However, every time you use new to create a new instance of that class, its non-static fields will be different. That is why you have to use this or, if in a different class, a reference to a specific instance in order to access them.
A clarification:
in getter methods it's not necessary to use the keyword this (as it's been shown in other answers). If you're new to Java this will introduce you to variable scopes (local variables vs instance variables). In other words the following works perfectly:
public class Foo {
private int x;
public void setX(int x) {
this.x = x; //Here the keywork this is necessary!
}
public int getX() {
return x; //in this case the 'x' can only be instance variable
}
}
There is also another important use of this for invoking constructors defined in the same class (You might want to check the keyword 'super' as well). Check the following:
public class HelloWorld {
public static void main(String[] args) {
Foo foo1 = new Foo();
Foo foo2 = new Foo(3, 4, 5);
System.out.println("Foo1:\n" + foo1);
System.out.println("Foo2:\n" + foo2);
}
}
class Foo {
private int x, y, z;
public Foo() {
this(-1, -1);
}
public Foo(int x, int y) {
this.x = x;
this.y = y;
}
public Foo(int x, int y, int z) {
this(x, y);
this.z = z;
}
#Override
public String toString() {
return "x= " + x + "\ny= " + y + "\nz= " + z + "\n";
}
}
Enjoy!
You can only use "this" from within an object instance.
"static", by definition, is OUTSIDE of ANY object.
Here's an excellent link in the Java documentation:
http://download.oracle.com/javase/tutorial/java/javaOO/classvars.html
'Hope that helps!
for static variables, use ClassName (like you did). For instance (non-static) variables, use this.variableName
you can use it to access instance variables and methods, you are getting this error because you are using this to access static variables.
and also ... java doesn't have =>, in java you use the .
objectName.variableName = newValue
Use this for getters/setters/constructors.
For example.
class Test {
int x;
int y;
public void Test(int x, int y) {
this.x=x;
this.y=y;
}
public void setX(int x) {
this.x=x;
}
}

How to access public constant variables of main class from a sub class?

I have a main class with a couple of public constant variables, and I have a custom class, I would like to know how can I access the constants of the main class from the custom class?
Main Class code:
import processing.core.*;
import toxi.geom.*;
import toxi.math.*;
public class VoronoiTest extends PApplet {
// this are the constants I want to access from the Site class
public static int NUM_SITES = 8;
public static int SITE_MAX_VEL = 2;
public static int SITE_MARKER_SIZE = 6;
Site[] sites;
public void setup() {
size( 400, 400 );
sites = new Site[NUM_SITES];
for ( int i = 0; i < sites.length; i++) {
sites[i] = new Site( this );
}
}
}
And this is the Site class code:
import processing.core.*;
public class Site {
PApplet parent;
float x, y;
PVector vel;
int c;
Site ( PApplet p ) {
parent = p;
// here I try to get the constants from the main class
vel = new PVector( parent.random(-parent.SITE_MAX_VEL, SITE_MAX_VEL), parent.random(-SITE_MAX_VEL, SITE_MAX_VEL) );
}
}
Any help will be much appreciated!
You can't. Because parent is of type PApplet, not VoronoiTest, you cannot guarantee that it has the static member SITE_MAX_VEL.
Conversely, if parent were of type VoronoiTest, there would be little point in accessing the static variable through the instance, as it would be impossible for it to change.
As already mentioned, to access static members, use the ClassName.STATIC_MEMBER notation (in this case, VoronoiTest.SITE_MAX_VEL).
Better yet though, just store the constants in the Site class instead. After all, that seems the most logical place for them.
import processing.core.*;
public class Site {
public static final int COUNT = 8;
public static final int MAX_VEL = 2;
public static final int MARKER_SIZE = 6;
PApplet parent;
float x, y;
PVector vel;
int c;
Site(PApplet p) {
parent = p;
vel = new PVector(
parent.random(-MAX_VEL, MAX_VEL),
parent.random(-MAX_VEL, MAX_VEL)
);
}
}
Use the VoronoiTest reference. VoronoiTest.SITE_MAX_VEL, for example. When you use a PApplet reference, the compiler doesn't have any way of knowing that the static variables exist.
Static fields are accessed via the class-name. Use VoronoiTest.SITE_MAX_VEL.

Categories