I am currently working on a small Java application and I ran into a problem. I create two different variables, but after I run the code, the first variable is getting the same value as the second one. They should be different.
Here is my custom file class:
public class MyFile {
private static String path;
private static String name;
private static final String FILE_SEPARATOR = "/";
public MyFile(String path) {
System.out.println(path);
this.path = "";
this.name = "";
this.path = /*FILE_SEPARATOR*/path;
String[] dirs = path.split(FILE_SEPARATOR);
this.name = dirs[dirs.length - 1];
}
public static String getPath() {
return path;
}
public static String getName() {
return name;
}
public String toString() {
return "Path: " + path + ", Name: " + name;
}
}
Here I am using the variables:
MyFile modelFile = new MyFile("res\\model.dae");
MyFile textureFile = new MyFile("res\\diffuse.png");
System.out.println(modelFile.toString());
System.out.println(textureFile.toString());
The output is the following: http://imgur.com/a/Nu3N6
In MyFile class, you declare these fields as static fields :
private static String path;
private static String name;
So you can assign to them a single value as a static field is shared among all instances of the class.
You should rather declare these fields as instance fields to have distinct values for each MyFile instance :
private String path;
private String name;
First you want to know about static keyword:
Attributes and methods(member of a class) can be defined as static.
static members do not belongs to an individual object.
static members are common to all the instances(objects of the same class).
static members are stores in static memory(a common memory location which can by everybody).
Becauseof two member variables are static. Each objects share the values of these two variables(values are common for every objects).
private static String path;
private static String name;
Remove the static in both variables. Then each and every object will hold a individual values for these variables.
When Defining an Entity class the class variable show be private period. Unless you want to access these variable statically, as in without having to instantiate the class or using getters and setter. If you use getters and setters as you have done above, and clearly made an instance of the class you want use ensure you don't use static access modifiers for the class variables.
The modified code is-as below.
package StackOverflowProblemSets;
/**
* Created by HACKER on 05/06/2017.
* Two different variables getting same value
*/
public class MyFile {
private String path;
private String name;
private static final String FILE_SEPARATOR = "/";
public MyFile(String path) {
System.out.println(path);
this.path = "";
this.name = "";
this.path = /*FILE_SEPARATOR*/path;
String[] dirs = path.split(FILE_SEPARATOR);
this.name = dirs[dirs.length - 1];
}
public String getPath() {
return path;
}
public String getName() {
return name;
}
public String toString() {
return "Path: " + path + ", Name: " + name;
}
public static void main(String[] args) {
MyFile modelFile = new MyFile("res\\model.dae");
MyFile textureFile = new MyFile("res\\diffuse.png");
System.out.println(modelFile.toString());
System.out.println(textureFile.toString());
}
}
You need to know about static and local variables.
Static variables of a class are such variables which are common to all instances of that class and are shared by all of the instances. E.g. if I have a class:
public static class myClass{
public static int staticVar;
//Constructor
public myClass(){
staticVar = 0;
}
}
and then I have the following code in a main method of another class:
public static void main(String args[]){
myClass c1, c2;
c1 = new myClass();
c2 = new myClass();
c1.staticVar = 4;
c2.staticVar = 8;
System.out.println(c1.staticVar + " " + c2.staticVar);
}
then my output will be:
8 8
This is because the variable staticVar is shared by both c1 and c2. First when the statement c1.staticVar = 4 is executed, the value of staticVar for both c1 and c2 is 4. Then the statement c2.staticVar = 8 is executed to change the value of staticVar of both classes to 8.
So in your problem, you have to make your name and path variables non-static to give each of your myFile instances a different value of the variables.
I hope this helps.
You problem is second file path is overlap of first file path. So, check this code:
MyFile modelFile = new MyFile("res\\model.dae");
MyFile textureFile = new MyFile("res\\diffuse.png");
System.out.println(new MyFile("res\\model.dae"));
System.out.println(new MyFile("res\\diffuse.png"));
Related
I've got only a main class in my small program and it's using a lot of path.
As they will not change while the program is running, I think I can put static in their declaration but not sure for the final. Moreover, I'm not sure where is the best place to declare my paths. Is it in the main class or just before?
Here's an example of my code:
package classtest;
public class ClassTest {
// Should I put the path here?
public static void main(String[] args) {
String dirPath = "C:/Users/test1/";
String pathOut = "C:/Users/stats.csv";
// or here?
}
}
An alternative approach is reading your paths from a Properties file:
Properties prop = new Properties();
And use the properties wherever you would like. It makes refactoring later very easy:
prop.getProperty("diPath");
prop.getProperty("pathOut");
It is more common to make your paths arguments, so they can be set by the person running the program.
public class ClassTest {
public static void main(String[] args) {
if (args.length < 2) {
System.err.println("Usage: java ClassTest {dir} {output}");
return;
}
String dirPath = args[0];
String pathOut = args[1];
}
}
final keyword means that the value will never reassigned.
static keyword let the variable be a class variable instead of instance variable.
An additional note, generally class constants are written in uppercase with underscore delimiter, so I changed the names.
So if you like to declare them "globally" the best is to use a code similar to the following.
public class ClassTest {
public static final String DIR_PATH = "C:/Users/test1/";
public static final String PATH_OUT = "C:/Users/stats.csv";
public static void main(String[] args) {
// Use DIR_PATH or PATH_OUT as needed
}
}
Note that the previous code is useful only if you reuse the DIR_PATH or PATH_OUT variables in different methods. Otherwise defining the variable local to the main method is correct to limit the visibility to the only portion of code using it.
You can do this kind of refactoring:
public class ClassTest {
// Specify a base path for all paths to be used
public static final String BASE_PATH = "C:/Users";
// 1. If these paths will be used in several methods, declare them here
public static final String dirPath = BASE_PATH + "/test1/";
public static final String pathOut = BASE_PATH + "/stats.csv";
public static void main(String[] args) {
// 2. If those paths will be used in the main method only, declare them here
final String dirPath = BASE_PATH + "/test1/";
final String pathOut = BASE_PATH + "/stats.csv";
}
}
Static members of a class should be declared outside the scope of any class method.
Try this .. It's the cleanest way :
public class ClassTest implements StaticPath {
public static void main(String[] args) {
System.out.print(PATH_OUT);
}
}
interface StaticPath {
public final static String PATH = "C:/Users/";
public final static String PATH_OUT = PATH + "stats.csv";
public final static String PATH_IN = PATH + "dyn.csv";
}
I have a class Components:
public class Components {
int numberOfNets;
String nameOfComp;
String nameOfCompPart;
int numOfPin;
public components(int i, String compName, String partName, int pin) {
this.numberOfNets = i;
this.nameOfComp = compName;
this.nameOfCompPart = partName;
this.numOfPin = pin;
}
}
Inside another class I created an arraylist of Components class:
List<Components> compList = new ArrayList<Components>();
Later in the code, I am adding the elements in List in this way:
compList.add(new Components(0,compName,partName,0));
See, here numberOfNets and numOfPin variables in Components class are initiated with 0 values. But these values are getting calculated/incremented in a later part of code and hence I need to update the new values of only these two variables in each list element. Now from ArrayList doc I get the idea of updating a list element using its index by set operation. But I am confused how to set/update a particular variable of a class in an ArrayList of a class. I need to update only these two mentioned variables, not all of the four variables in Components class. Is there any way to do that?
You should add getter/setter to your component class so that outer class can update component's members
public class Components {
private int numberOfNets;
private String nameOfComp;
private String nameOfCompPart;
private int numOfPin;
public components(int i, String compName, String partName, int pin) {
setNumberOfNets(i);
setNameOfComp(compName);
setNameOfCompPart(partName);
setNumOfPin(pin);
}
public void setNumberOfNets(int numberOfNets) {
this.numberOfNets = numberOfNets;
}
// Similarly other getter and setters
}
You can now modify any data by using following code because get() will return reference to original object so modifying this object will update in ArrayList
compList.get(0).setNumberOfNets(newNumberOfNets);
Example code.
public class Main {
public static void main(String[] args) {
List<Components> compList = new ArrayList<Components>();
compList.add(new Components(0, "compName", "partName", 0));
System.out.println(compList.get(0).toString());
compList.get(0).numberOfNets = 3;
compList.get(0).numOfPin = 3;
System.out.println(compList.get(0).toString());
}
}
Your class.
public class Components {
int numberOfNets;
String nameOfComp;
String nameOfCompPart;
int numOfPin;
public Components(int i, String compName, String partName, int pin) {
this.numberOfNets = i;
this.nameOfComp = compName;
this.nameOfCompPart = partName;
this.numOfPin = pin;
}
public String toString() {
return this.numberOfNets + " " + nameOfComp + " " + nameOfCompPart
+ " " + numOfPin;
}
}
The output:
0 compName partName 0
3 compName partName 3
I have a field and a local variable with same name. How to access the field?
Code:
String s = "Global";
private void mx()
{
String s = "Local";
lblB.setText(s); // i want global
}
In c++ use :: operator like following:
::s
Is were :: operator in Java?
That's not a global variable - it's an instance variable. Just use this:
String s = "Local";
lblB.setText(this.s);
(See JLS section 15.8.3 for the meaning of this.)
For static variables (which are what people normally mean when they talk about global variables), you'd use the class name to qualify the variable name:
String s = "Local";
lblB.setText(ClassDeclaringTheVariable.s);
In most cases I prefer not to have a local variable with the same name as an instance or static variable, but the notable exception to this is with constructors and setters, both of which often make sense to have parameters with the same name as instance variables:
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
You can use "this" keyword to do this.
Example:
public class Test {
private String s = "GLOBAL";
public Test() {
String s = "LOCAL";
//System.out.println(this.s);
//=> OR:
System.out.println(s);
}
public static void main(String[] args) throws IOException {
new Test();
}
}
Using this keyword you can use the global one but inside the same class. Or simply you can declare global variable static and access the same using classname.variable name.
Yes you can also use
class _ name.Globalvariable_name
Class simple
{
static int i;
public static void main(string args[])
{
int i=10;
System.out.println("Local Variable I =" +i) ;
system.out.println("Global variable I =" +Simple.i)
}
}
I am working on a homework assignment. I am confused on how it should be done.
The question is:
Create a class called IDCard that contains a person's name, ID number,
and the name of a file containing the person's photogrpah. Write
accessor and mutator methods for each of these fields. Add the
following two overloaded constructors to the class:
public IDCard() public IDCard(String n, int ID, String filename)
Test your program by creating different ojbects using these two
constructors and printing out their values on the console using the
accessor and mutator methods.
I have re-written this so far:
public class IDCard {
String Name, FileName;
int ID;
public static void main(String[] args) {
}
public IDCard()
{
this.Name = getName();
this.FileName = getFileName();
this.ID = getID();
}
public IDCard(String n, int ID, String filename)
{
}
public String getName()
{
return "Jack Smith";
}
public String getFileName()
{
return "Jack.jpg";
}
public int getID()
{
return 555;
}
}
Let's go over the basics:
"Accessor" and "Mutator" are just fancy names fot a getter and a setter.
A getter, "Accessor", returns a class's variable or its value. A setter, "Mutator", sets a class variable pointer or its value.
So first you need to set up a class with some variables to get/set:
public class IDCard
{
private String mName;
private String mFileName;
private int mID;
}
But oh no! If you instantiate this class the default values for these variables will be meaningless.
B.T.W. "instantiate" is a fancy word for doing:
IDCard test = new IDCard();
So - let's set up a default constructor, this is the method being called when you "instantiate" a class.
public IDCard()
{
mName = "";
mFileName = "";
mID = -1;
}
But what if we do know the values we wanna give our variables? So let's make another constructor, one that takes parameters:
public IDCard(String name, int ID, String filename)
{
mName = name;
mID = ID;
mFileName = filename;
}
Wow - this is nice. But stupid. Because we have no way of accessing (=reading) the values of our variables. So let's add a getter, and while we're at it, add a setter as well:
public String getName()
{
return mName;
}
public void setName( String name )
{
mName = name;
}
Nice. Now we can access mName. Add the rest of the accessors and mutators and you're now a certified Java newbie.
Good luck.
You need to remove the static from your accessor methods - these methods need to be instance methods and access the instance variables
public class IDCard {
public String name, fileName;
public int id;
public IDCard(final String name, final String fileName, final int id) {
this.name = name;
this.fileName = fileName
this.id = id;
}
public String getName() {
return name;
}
}
You can the create an IDCard and use the accessor like this:
final IDCard card = new IDCard();
card.getName();
Each time you call new a new instance of the IDCard will be created and it will have it's own copies of the 3 variables.
If you use the static keyword then those variables are common across every instance of IDCard.
A couple of things to bear in mind:
don't add useless comments - they add code clutter and nothing else.
conform to naming conventions, use lower case of variable names - name not Name.
I have a problem where each element of my array seem to be reassigned.
class Car {
private static int nom = 0;
private static String whee = "";
public void setCar(int r, String s) {
this.nom = r;
this.whee = s;
}
}
class Rawr {
private Car[] jar = new Car[3];
public Mar() {
jar[0] = new Car();
jar[1] = new Car();
jar[2] = new Car();
jar[0].setCar(2, "yar");
jar[1].setCar(3, "tar");
jar[2].setCar(4, "sars");
}
}
If I printed it like jar[0].nom + jar[0].whee + jar[1].nom + jar[2].whee + jar[3].whee, the output would be
4 sars 4 sars sars
It's because your variables are static i.e. they belong to the class, rather than to an instance. Take a look at Java Tutorials | Understanding Instance and Class Members for more information about what this means.
You should remove the static keyword, so that they become instance variables.
Change
private static int nom = 0;
private static String whee = "";
to
private int nom = 0;
private String whee = "";
static means the variable is shared by all instances. (The fact you can use this to refer to static variables is a Java oddity.)
Your nom and whee fields are static. This means that they are tied to the class, and not to the object (instance) of the class.
Thus, when you assign a new value to this.nom, in reality, you assign a the value to Car.nom. The compiler allows referring to static variables through an object, but it's very bad practice. You should always refer to static fields by their class : Car.nom, Car.whee. This makes it clear that the nom and whee are static, and thus shared by all instances of the class. In this case, these fields should not be static : each Car instance has its own name and whee (whatever it might be).
A better way to structure your code is as follows.
class Car {
private final int nom;
private final String whee;
public Car(int nom, String whee) {
this.nom = nom;
this.whee = whee;
}
public String toString() { return num + " " + whee; }
}
class Rawr {
private final Car[] jar = {new Car(2, "yar"), new Car(3, "tar"), new Car(4, "sars")};
public String toString() {
return Arrays.toString(jar);
}
}