Java variables overwriting - java

I have a program with a for that take strings from an Arraylist, split them and sends them to a Worker class.
Worker Class:
public class WorkerRSR extends SwingWorker<String, Void>{
private static String urlFrames;
private static String urlImg;
public static int bool;
public static int dist;
public static int numI;
public static int spra;
public static boolean isCoda;
public static int numCoda;
public static String algo;
public WorkerRSR(String urlImg, int dist, int numI, int spra, String algo, String urlFrames, boolean isCoda, int numCoda) {
this.urlImg=urlImg;
this.dist=dist;
this.numI=numI;
this.spra=spra;
this.algo=algo;
this.urlFrames=urlFrames;
this.isCoda = isCoda;
this.numCoda = numCoda;
//FIRST CHECK POINT
}
#Override
protected String doInBackground() throws Exception {
PanelRSR_LRSR.getProgessbar().setIndeterminate(true);
go();
return "";
}
#Override
protected void done() {
System.out.println("Algoritmo RSR esguito");
if(isCoda){
CreateOption.codaCont++;
System.out.println("RSR codaCont: "+CreateOption.codaCont);
if(CreateOption.codaCont==CreateOption.csize){
JOptionPane.showMessageDialog(null,"Coda Eseguita", "Attenzione",JOptionPane.WARNING_MESSAGE);
PanelRSR_LRSR.getProgessbar().setIndeterminate(false);
}
}
else{
PanelRSR_LRSR.getProgessbar().setIndeterminate(false);
JOptionPane.showMessageDialog(null,"Finito RSR", "Attenzione",JOptionPane.WARNING_MESSAGE);
}
}
public static void go() throws IOException{
System.out.println("ESEGUO RSR, attendi...");
//SECOND CHECK POINT
System.out.println("RSR n = "+numI+" codaCont: "+CreateOption.codaCont+" numCoda = "+numCoda);
while(true){
if(numCoda==CreateOption.codaCont)
break;
}
MakeRSR m=new MakeRSR();
String name = urlImg.substring(urlImg.lastIndexOf("\\"),urlImg.lastIndexOf("."));
String output=name.substring(1); //?
String urlOutput=urlFrames+"\\finalRSR\\"+name+"-"+algo+"-dist"+dist+"-n"+numI+"-N"+spra+".png";
m.RSR(urlImg,urlOutput,dist,numI,spra);
}
}
The problem is that this class is going to be called multiple times and every time it overwrite the previous values of the varables: if I check them at the first Checkpoint they are different (probably beacuse the second acquisition yet has to be made), but at the second Checkpoint they are the same.
How can I let them stay different?

These variables shouldn't be static if they are set by the constructor. They should be instance variables, so each instance of your class can have different values.
public class WorkerRSR extends SwingWorker<String, Void>{
private String urlFrames;
private String urlImg;
private int bool;
private int dist;
private int numI;
private int spra;
private boolean isCoda;
private int numCoda;
private String algo;
public WorkerRSR(String urlImg, int dist, int numI, int spra, String algo, String urlFrames, boolean isCoda, int numCoda) {
this.urlImg=urlImg;
this.dist=dist;
this.numI=numI;
this.spra=spra;
this.algo=algo;
this.urlFrames=urlFrames;
this.isCoda = isCoda;
this.numCoda = numCoda;
//FIRST CHECK POINT
}
...
}
You should also change all those variables to be private. If they should be accessed from outside the class, they should be accessed via getter methods.

Related

Changing inherited parameters from super to sub class

I have an assignment about doctors and prescriptions. In one of the classes I am not supposed to use int reit in the constructor (a sub class), as the super class have. The hint in the assignment is that int reit should always start on 3 when the prescription is made (how many times one can use the prescription). How am I supposed to change it from int reit to 3 (as I understood from a hint from an instructor in class).
Everythings in norwegian because we have to, hope that's okay.
Thanks for any help!
Here is the first class:
public abstract class Resept {
protected int id = 0;
protected static int teller = 1;
protected int pasientID = 0;
protected int reit = 0;
protected Legemiddel legemiddel;
protected Lege utskrivendeLege;
public Resept(Legemiddel legemiddel, Lege utskrivendeLege, int pasientID, int reit) {
this.legemiddel = legemiddel;
this.utskrivendeLege = utskrivendeLege;
this.id = teller;
this.reit = reit;
this.pasientID = pasientID;
}
}
Here is the next:
public class HvitResept extends Resept {
public HvitResept(Legemiddel legemiddel, Lege utskrivendeLege, int pasientID, int reit) {
super(legemiddel, utskrivendeLege, pasientID, reit);
}
}
And in this next class we're not supposed to write int reit in the constructor. Reit is always 3 with a new P-resept (birth control prescription).
public class PResept extends HvitResept {
public PResept(Legemiddel legemiddel, Lege utskrivendeLege, int pasientID, **int reit**) {
super(legemiddel, utskrivendeLege, pasientID, reit);
}
}
public class PResept extends HvitResept {
public PResept(Legemiddel legemiddel, Lege utskrivendeLege, int pasientID) {
super(legemiddel, utskrivendeLege, pasientID, 3);
}
}
You can call super(...);with the values you desire. super will call the constructor of its parent class.
public class PResept extends HvitResept {
private static final int reit = 3;
public PResept(Legemiddel legemiddel, Lege utskrivendeLege, int pasientID) {
super(legemiddel, utskrivendeLege, pasientID, reit);
}
}
Declaring this variable as private static and final will not occupy every time when we create new object of type PResept and also the value can't be changed due to final.

How to Count Number of Instances of a Class

Can anyone tell me how to count the number of instances of a class?
Here's my code
public class Bicycle {
//instance variables
public int gear, speed, seatHeight;
public String color;
//constructor
public Bicycle(int gear, int speed, int seatHeight, String color) {
gear = 0;
speed = 0;
seatHeight = 0;
color ="Unknown";
}
//getters and setters
public int getGear() {
return gear;
}
public void setGear(int Gear) {
this.gear = Gear;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int Speed){
this.speed = Speed;
}
public int getSeatHeight() {
return seatHeight;
}
public void setSeatHeight(int SeatHeight) {
this.seatHeight = SeatHeight;
}
public String getColor() {
return color;
}
public void setColor(String Color) {
this.color = Color;
}
}//end class
public class Variable extends Bicycle {
public Variable(int gear, int speed, int seatHeight, String color) {
super(gear, speed, seatHeight, color);
}
}//end class
public class Tester {
public static void main(String args[]){
Bicycle bicycle1 = new Bicycle(0, 0, 0, null);
bicycle1.setColor("red");
System.out.println("Color: "+bicycle1.getColor());
bicycle1.setSeatHeight(4);
System.out.println("Seat Height: "+bicycle1.getSeatHeight());
bicycle1.setSpeed(10);
System.out.println("Speed: "+bicycle1.getSpeed());
bicycle1.setGear(6);
System.out.println("Gear: "+bicycle1.getGear());
System.out.println("");//space
Bicycle bicycle2 = new Bicycle(0, 0, 0, null);
bicycle2.setColor("black");
System.out.println("Color: "+bicycle2.getColor());
bicycle2.setSeatHeight(6);
System.out.println("Seat Height: "+bicycle2.getSeatHeight());
bicycle2.setSpeed(12);
System.out.println("Speed: "+bicycle2.getSpeed());
bicycle2.setGear(6);
System.out.println("Gear: "+bicycle2.getGear());
System.out.println("");//space
}//end method
}//end class
The class variable is to be used to keep count of the number of instances of the Bicycle class created and the tester class creates a number of instances of the Bicycle class and demonstrates the workings of the Bicycle class and the class variable. I've looked all over the internet and I can't seem to find anything, could someone show me how to do it please, thanks in advance :)
Since static variables are initialized only once, and they're shared between all instances, you can:
class MyClass {
private static int counter;
public MyClass() {
//...
counter++;
}
public static int getNumOfInstances() {
return counter;
}
}
and to access the static field counter you can use MyClass.getNumOfInstances()
Read more about static fields in the JLS - 8.3.1.1. static Fields:
If a field is declared static, there exists exactly one incarnation of the field, no matter how many instances (possibly zero) of the class may eventually be created. A static field, sometimes called a class variable, is incarnated when the class is initialized (§12.4).
Note that counter is implicitly set to zero
Pleae try the tool of java
jmap -histo <PDID>
Out put
num #instances #bytes class name
----------------------------------------------
1: 1105141 97252408 java.lang.reflect.Method
2: 3603562 86485488 java.lang.Double
3: 1191098 28586352 java.lang.String
4: 191694 27035744 [C
In addition, you should override finalize method to decrement the counter
public class Bicycle {
...
public static int instances = 0;
{
++instances; //separate counting from constructor
}
...
public Bicycle(int gear, int speed, int seatHeight, String color) {
gear = 0;
speed = 0;
seatHeight = 0;
color ="Unknown";
}
#Override
protected void finalize() {
super.finalize();
--instances;
}
}
You should have in mind that static variables are CLASS scoped (there is no one for each instance, only one per class)
Then, you could demonstrate instance decrement with:
...
System.out.println("Count:" + Bicycle.getNumOfInstances()); // 2
bicycle1 = null;
bicycle2 = null;
System.gc(); // not guaranteed to collect but it will in this case
Thread.sleep(2000); // you expect to check again after some time
System.out.println("Count again:" + Bicycle.getNumOfInstances()); // 0
why not using a static counter?
public class Bicycle {
private static int instanceCounter = 0;
//instance variables
public int gear, speed, seatHeight;
public String color;
//constructor
public Bicycle(int gear, int speed, int seatHeight, String color) {
gear = 0;
speed = 0;
seatHeight = 0;
color ="Unknown";
instanceCounter++;
}
public int countInstances(){
return instanceCounter;
}
........
You just need static counter in class.
public class Bicycle {
private static volatile int instanceCounter;
public Bicycle() {
instanceConter++;
}
public static int getNumOfInstances() {
return instanceCounter;
}
protected void finalize() {
instanceCounter--;
}
}
As mentioned in many comments finalize() is not recommended to use so there could be another approach to count the Bicycle instances -
public class Bicycle {
private static final List<PhantomReference<Bicycle>> phantomReferences = new LinkedList<PhantomReference<Bicycle>>();
private static final ReferenceQueue<Bicycle> referenceQueue = new ReferenceQueue<Bicycle>();
private static final Object lock = new Object();
private static volatile int counter;
private static final Runnable referenceCleaner = new Runnable() {
public void run() {
while (true) {
try {
cleanReferences();
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
static {
Thread t = new Thread(referenceCleaner);
t.setDaemon(true);
t.start();
}
private Bicycle() {
}
public static Bicycle getNewBicycle() {
Bicycle bicycle = new Bicycle();
counter++;
synchronized (lock) {
phantomReferences.add(new PhantomReference<Bicycle>(new Bicycle(), referenceQueue));
}
System.out.println("Bicycle added to heap, count: " + counter);
return bicycle;
}
private static void cleanReferences() {
try {
PhantomReference reference = (PhantomReference) referenceQueue.remove();
counter--;
synchronized (lock) {
phantomReferences.remove(reference);
}
System.out.println("Bicycle removed from heap, count: " + counter);
} catch (Exception e) {
e.printStackTrace();
}
}
public static int getNumOfBicycles() {
return counter;
}
}
public class BicycleTest {
public static void main(String[] args) {
int i = 0;
while (i++ < 1000) {
Bicycle.getNewBicycle();
}
while (Bicycle.getNumOfBicycles() > 0) {
try {
Thread.sleep(1000);
System.gc(); // just a request
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Alternatively, you can create a counter with an initializer block and a static variable.
class SomeClass
{
private static int instanceCounter;
{
instanceCounter++;
}
}
Initializer blocks get copied by the compiler into every constructor, so, you will have to write it once no matter how many constructors you will need (As referred into the above link). The block in {} runs every time you create a new object of the class and increases the variable counter by one.
And of course get the counter by something like:
public static int getInstanceCounter()
{
return instanceCounter;
}
or directly
int numOfInstances = SomeClass.instanceCounter;
If you do not make numOfInstances private
One basic approach is to declare a static numeric member field thats incremented each time the constructor is invoked.
public class Bicycle {
//instance variables
public int gear, speed, seatHeight;
public String color;
public static int bicycleCount = 0;
//constructor
public Bicycle(int gear, int speed, int seatHeight, String color) {
gear = 0;
speed = 0;
seatHeight = 0;
color ="Unknown";
bicycleCount++;
}
...
}
If you want to count and test instances based on the number of objects created, you can use a loop to see what really is happening. Create a constructor and use a static counter
public class CountInstances {
public static int count;
public CountInstances() {
count++;
}
public int getInstaces() {
return count;
}
public static void main(String []args) {
for(int i= 0; i<10; i++) {
new CountInstances();
}
System.out.println(CountInstances.count);
}
}
public class Number_Objects {
static int count=0;
Number_Objects(){
count++;
}
public static void main(String[] args) {
Number_Objects ob1=new Number_Objects();
Number_Objects ob2=new Number_Objects();
Number_Objects obj3=new Number_Objects();
System.out.print("Number of objects created :"+count);
}
}

Wrong result accessing device by JNA

I trying to access a device using JNA
The first command return a statusCode 263 insteadof zero.
I searched and found this code, means "INVALID_DEVICE_NAME". The device's manual say:
The MCI_OPEN_TYPE flag must be specified and the lpstrDeviceType member of the structure identified by lpOpen must contain the device
name (in our case “DictCtrl”).
Is there any error in my code?
The "same" code works in a compiled delphi application, my device is recognized.
public class Main {
public static final int MCI_OPEN = 0x0803;
public static final int MCI_OPEN_TYPE = 0x00002000;
public static final int MCI_STATE_STOP = 0x00000001;
public static final int MCI_OPEN_SHAREABLE = 0x00000100;
public static Winmm winmmLib = Winmm.INSTANCE;
public interface Winmm extends StdCallLibrary {
Winmm INSTANCE = (Winmm) Native.loadLibrary("winmm", Winmm.class);
int mciSendCommandA(int IDDevice, int uMsg, int fdwCommand, Structure dwParam);
}
public static class TagmciOpenParmsa extends Structure {
public int dwCallback;
public int wDeviceID;
public String lpstrDeviceType;
public String lpstrElementName;
public String lpstrAlias;
#Override
protected List getFieldOrder() {
return Arrays.asList(new String[] { "dwCallback", "wDeviceID", "lpstrDeviceType", "lpstrElementName", "lpstrAlias" });
}
}
public static void main(String[] args) {
TagmciOpenParmsa tagmciOpenParmsa = new TagmciOpenParmsa();
tagmciOpenParmsa.lpstrDeviceType = "DictCtrl";
int ret = winmmLib.mciSendCommandA(0, MCI_OPEN, MCI_OPEN_TYPE, tagmciOpenParmsa); // | MixerConstants.MCI_OPEN_SHAREABLE
System.out.println(ret);
}
}

Java // variable initialisation ERROR

so i am trying to compile this code and i get : ERROR : variable Laptop might not have been initiated.
public class Computer{
String modelName;
String motherboard;
String systemType;
int ram;
int cpu
int hdd;
public static void main(String[] args){
Computer Laptop;
Laptop.modelName = "M610";
Laptop.motherboard = "MSI";
Laptop.systemType = "Linux";
Laptop.ram = 2048;
Laptop.hdd = 50;
Laptop.cpu = 1500;
System.out.println("Model name:"+Laptop.modelName);
System.out.println("Motherboard:"+Laptop.motherboard);
System.out.println("System type: "+Laptop.systemType);
System.out.println("RAM :"+Laptop.ram);
System.out.println("HDD:"+Laptop.hdd);
System.out.println("CPU :"+Laptop.cpu);
}
}
Thank you very much in advance !
You need to do what the message says: Initialize Laptop.
Replace:
Computer Laptop;
With:
Computer Laptop = new Computer();
The former declares a new variable which the latter initializes it.
Yup as have been said, you need to instantiate the class so you have to do
Computer laptop = new Computer(); // Note lower case laptop as this is how you should define variable names
What you have wrote will do, but have a look at this example. Its more of a "correct way" in java
public class Laptop {
private String modelName;
private String motherboard;
private String systemType;
private int ram;
private int cpu;
private int hdd;
public static void main(String[] args) {
Laptop laptop = new Laptop();
laptop.setModelName("M610");
laptop.setMotherboard("MSI");
laptop.setSystemType("Linux");
laptop.setRam(2048);
laptop.setCpu(50);
laptop.setHdd(1500);
laptop.printResult();
}
public void printResult() {
System.out.println("Model name:" + getModelName());
System.out.println("Motherboard:" +getModelName());
System.out.println("System type: "+ getSystemType());
System.out.println("RAM :" + getRam());
System.out.println("HDD :" + getHdd());
System.out.println("CPU :" + getCpu());
}
public String getModelName() {
return modelName;
}
public void setModelName(String modelName) {
this.modelName = modelName;
}
public String getMotherboard() {
return motherboard;
}
public void setMotherboard(String motherboard) {
this.motherboard = motherboard;
}
public String getSystemType() {
return systemType;
}
public void setSystemType(String systemType) {
this.systemType = systemType;
}
public int getRam() {
return ram;
}
public void setRam(int ram) {
this.ram = ram;
}
public int getCpu() {
return cpu;
}
public void setCpu(int cpu) {
this.cpu = cpu;
}
public int getHdd() {
return hdd;
}
public void setHdd(int hdd) {
this.hdd = hdd;
}
}
There are two ways to solve this problem.
Declare all your fields as static
public class Computer{
static String modelName;
static String motherboard;
.
.
.
In this case there is no need of initialization. Static members belong to a class rather than to a specific initialization or an instance of it.
Access them as Computer.your-filedname.
However if you want to declare an object.
You can just change this line
Computer Laptop;
to this
Computer Laptop = new Computer();
i.e. you initialize your object before assigning your fields' values in subsequent lines.

Inheritance in Java printing null

I have a problem with the inheritance of classes.
here is my Java code:
public class spaarRekening extends rekening{
private double rente;
public double getRente(){
return rente;
}
spaarRekening(String rN, int s, double d){
super(rN, s);
rente = d;
}
spaarRekening sR = new spaarRekening("456", 999999, 2.5);
}
public static class rekening implements rekeningIF{
int saldo;
static String rekeningNummer;
rekening(String rN, int s){
rekeningNummer = rN;
saldo = s;
}
public static String getRekeningNummer(){
return rekeningNummer;
}
public int getSaldo(){
return saldo;
}
}
I want to let the spaarRekening be printed out by:
System.out.printf("Uw rekeningnummer is: %s\n", spaarRekening.getRekeningNummer());
But it prints out null.
Why is this?
Thanks.
Don't use static. Not until you understand how it works and where it is applicable.
Since you never create any object of type spaarRekening or rekening the variable rekeningNummer never gets initialized, because you do intialization inside the constructor.
You most probably want to make your rekeningNummer non-static when you initialize it inside the constructor.
When you really want it to be static then you should initialize it in a static way, too. Therefore remove the code from the constructor and initialize it right away when declaring.
public class SpaarRekening extends Rekening{
private double rente;
SpaarRekening(String rN, int s, double d){
super(rN, s);
rente = d;
}
public double getRente(){
return rente;
}
public static void main(String[] args) {
SpaarRekening sR = new SpaarRekening("456", 999999, 2.5d);
System.out.println(sR.getRekeningNummer());
}
}
public class Rekening implements RekeningIF{
protected int saldo;
protected String rekeningNummer;
Rekening(String rN, int s){
rekeningNummer = rN;
saldo = s;
}
public String getRekeningNummer(){
return rekeningNummer;
}
public int getSaldo(){
return saldo;
}
}
Your rekeningNummer is a static variable and of typeObject and in your code. The variable has not been intialized, hence it printed null.
You have to initialize the static variable before using it:
public static class Rekening implements RekeningIF{
int saldo;
static String rekeningNummer = ""; // initialized to empty String
Rekening(String rN, int s){
rekeningNummer = rN;
saldo = s;
}
public static String getRekeningNummer(){
return rekeningNummer;
}
// Provide method for setting value of rekeningNumber
public static void setRekeningNumber(String number) {
rekening.rekeningNummer = number;
}
public int getSaldo(){
return saldo;
}
}
You never initialize rekeningNummer, and the default value is null.
You never initialized the rekeningNummer, you may think that the statement spaarRekening sR = new spaarRekening("456", 999999, 2.5);within yourspaarRekening class will initialize it, but you are putting it within class definition, you are not actually instantiating any spaarRekening instance. Remove that statement, and instantiating it at some other places in your code

Categories