I've asked this question Adding objects to an array. And now it has brought up another question.
Is there a difference between this:
For class Patient:
public Patient(String ptNo, String ptName, int procType) throws IOException
{
Patient.patientNo = ptNo;
Patient.patientName = ptName;
Patient.procedureType = procType;
}
and this:
public Patient(String ptNo, String ptName, int procType) throws IOException
{
this.patientNo = ptNo;
this.patientName = ptName;
this.procedureType = procType;
}
I thought they were the same thing?
edit
I have created these in the Patient class.
private static String patientNo;
private static String procedureDate;
private static String patientName;
this is used to the access the properties that belong to an object whereas Classname is used to access the properties that belong to a class. Properties belonging to a class/static attributes means that those will be shared by all the objects.
Suggested reading: Understanding Instance and Class Members
public Patient(String ptNo, String ptName, int procType) throws IOException
{
Patient.patientNo = ptNo;
Patient.patientName = ptName;
Patient.procedureType = procType;
}
This code will only work if all three variables are static like this
public class Patient
{
static String patientNo;
static int procedureType;
static String patientName;
public Patient(String ptNo, String ptName, int procType) throws IOException
{
Patient.patientNo = ptNo;
Patient.patientName = ptName;
Patient.procedureType = procType;
}
}
Whereas something like this
public Patient(String ptNo, String ptName, int procType) throws IOException
{
this.patientNo = ptNo;
this.patientName = ptName;
this.procedureType = procType;
}
will work for non static variables, "this" simply is used to avoid confusion denote the object whose constructor is being called. Example
Patient p = new Patient("A","B",1);
would be same as saying
p.patientNo = ptNo;
p.patientName = ptName;
p.procedureType = procType;
EDIT
"this" comes to rescue in a situation like this
public class Patient
{
String patientNo;
int procedureType;
String patientName;
public Patient(String patientNo, String patientName, int procedureType) throws IOException
{
this.patientNo = patientNo; // variables in LHS are class members, RHS are method parameters
this.patientName = patientName;
this.procedureType = procedureType;
}
}
You use this to access to the non-static members of the class, whereas ClassName is used to access the static members. The non-static fields of a class are unique to each instance of the class, whereas the static fields are common to all instances.
class Test{
String txt;
static String sTxt;
public Test(String t) {
this.txt = t; // accessing the instance variable using this
}
}
class Test2{
void someMethod(){
Test t = new Test("someString");
Test.sTxt; // Accessing the static member, using classname
}
}
this is used to access Object properties. It is typically used to access non-static variables of the class, as they are associated with the object.
className is typically used to access static variables, as static variables are associated with the class.
Static variable are initialized when class loads where as object variable are initialized only when object of class is created.
Related
I apologize if this is a basic question.
I am attempting to create several unique objects in one class, then get the values of one of the objects in another class.
I have created two classes and followed some examples to end with this
public class Type {
public String name;
public int healthmod;
public int strmod;
public int accmod;
public int armmod;
public int refmod;
public int intmod;
public String advantages;
public String disadvantages;
public Type() {
Type fire = new Type();
fire.name = "Fire";
fire.healthmod = 0;
fire.strmod = 1;
fire.accmod = 0;
fire.armmod = 0;
fire.refmod = 0;
fire.intmod = 1;
}
}
and then in the main class:
Player.typename = Type.fire.name;
Edit
public class Player {
public static String name, classname, racename, elementname;
public static int maxhealth, healthpts, healthptscost, healthupgnum, healthmod, currenthealth, basehealth;
public static int str, strpts, strptscost, strupgnum, strmod;
public static int acc, accpts, accptscost, accupgnum, accmod;
public static int arm, armpts, armptscost, armupgnum, armmod;
public static int ref, refpts, refptscost, refupgnum, refmod;
public static int intelligence, intpts, intptscost, intupgnum, intmod;
public static int mana, maxmana, managain, managainak;
public static int hitChance, critChance, Level, statPts, statTotal, damage, damageDealt, goldmult, itemmod, itemdefboost, itemdamboost, itemmodboost;
public static String[] focusStats;
}
What I am trying to do is create a few objects in the Type class and access them in the Main class in order to store the values in the Player class, but in the Main class, fire "cannot be resolved or is not a field"
Edited to provide more clarity on the purpose.
You are completely mixing things here.
In the concstructor of Type you are creating a new local Object named fire. This object is only available in this constructor and not outside of it, e.g. in the main class.
A valid solution can only be found if you give more information about what you try to accomplish.
I could write like that your Type construct:
public Type() {
this.name = "Fire";
this.healthmod = 0;
this.strmod = 1;
this.accmod = 0;
this.armmod = 0;
this.refmod = 0;
this.intmod = 1;
}
So when using the Player class in your Main method, like that:
public static void main(String args[]) {
Type type = new Type();
Player.typename = type.name;
}
You can also put a reference of type inside Player class like that:
public class Player {
public static Type fire;
}
So in your main method like that:
public static void main(String args[]) {
Player.fire = new Type();
System.out.println(Player.fire.name);
}
I noticed a scenario today. When we pass a parameter on private methods, the entity will return the revised values but not primitives.
Here is my sample code,
/**
* #author gowthami
*
*/
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
String s = "gowth";
System.out.println("before " + s);
concateMe(s, "ami");
System.out.println("after " + s);
BeanTest bt = new BeanTest();
bt.setId("1");
System.out.println("before");
System.out.println(bt.getId());
System.out.println(bt.getName());
setBeanTestName(bt, "gowthami");
System.out.println("after");
System.out.println(bt.getId());
System.out.println(bt.getName());
String st = new String("gowth");
System.out.println("before " + st);
concateMe(st, "ami");
System.out.println("after " + st);
}
private static void setBeanTestName(BeanTest bt, String string) {
bt.setName(string);
}
private static void concateMe(String s, String string) {
s = s+string;
System.out.println("inside method " + s);
}
}
BeanTest.java
public class BeanTest {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
So the bean is getting updated even though we are not returning it from private method but a string is not. Can someone explain me whats happening on JVM level?
This is because Java follows Call by value, not Call by reference.
When you are passing s you are actually passing value of s, not the actual s. So though you are changing s in concateMe(), it will not change in your main method.
When you are passing bt, then the change is affecting as you are changing the field variable of that reference. But if you change the reference, then there will be no effect. You can add this in main method:
System.out.println("before......");
System.out.println(bt.getId());
System.out.println(bt.getName());
changeBeanTest(bt);
System.out.println("after");
System.out.println(bt.getId());
System.out.println(bt.getName());
Suppose your changeBeanTest is like this:
private static void changeBeanTest(BeanTest tempBeanTest) {
BeanTest bt = new BeanTest();
bt.setId("2");
bt.setName("Trump");
tempBeanTest = bt;
}
run this. There will be no change to bt sent from main().
The Bean is a full object in java passed by reference to the private method so it is the same instance in the main method and the private method.
You are modifying the values of that instance so the changes show up in both places.
The string is more or less a primitive and passed as a copy of the value instead of the exact instance from main. It is a new instance in the private method and so you are modifying a new variable. The changes don't show up in the main method as it is a different entity.
String s = "gowth"; in this line s is pointing to "gowth" from String Pool.When you are calling
private static void concateMe(String s, String string) here String s is different from caller method String s.Here String s scope is local to method ContactMe,But contactMe local String s pointing same "gowth" which is pointed by Caller class String s.After s = s + string;since String is immutable the method local reference String s pointing a different String "gowthami",but caller method String s is still pointing to "gowth".So you are getting this output.
But in case of Bean both the object pointing same String reference,Once we made any change in reference it would be reflected for both object.
I wrote some classes in Java but when I run the program I receive the error "ArrayIndexOutOfBoundsException", the incriminate class is this:
public class Bank {
private String name;
private int maxbankaccount;
private int activebankaccount;
private String radice = "IT8634";
private Conto[] bankaccount = new Conto[maxbankaccount];
public void addconto(String cf) {
bankaccount[activebankaccount] = new Conto(radice + activebankaccount , cf);
activebankaccount++;
}
public Bank(String name, int maxbankaccount) {
this.name = name;
this.maxbankaccount = maxbankaccount;
}
}
I wrote a tester class to test :
public class TestBank {
public static void main (String[] args) {
Bank b1 = new Bank("Fidelity", 10);
b1.addconto("PROVA");
}
}
Since I didn't seem to have made logical errors using the array I debugged, I realized that in the creation of the array of objects the maxbankaccount variable isn't 10 (value passed in Test) but as default value (0),then I tried passing 10 directly and it works good. Why is not the value 10 of maxbankaccount passed but 0?
private Conto[] bankaccount = new Conto[maxbankaccount];
This initialization takes place before the rest of the constructor runs.
Move it into the constructor:
public Bank(String name, int maxbankaccount) {
this.name = name;
this.maxbankaccount = maxbankaccount;
this.bankaccount = new Conto[maxbankaccount];
}
You have indeed made a logical error. The array bankaccount is getting initialized when the class is instantiated and is always 0.
Move it into the constructor and initialize it.
public Bank(String name, int maxbankaccount) {
/* ... */
this.bankaccount = new Conto[maxbankaccount];
}
Further more than the issues that are in the other answers, this
private int activebankaccount;
does not initialize the variable activebankaccount
So in:
public void addconto(String cf) {
bankaccount[activebankaccount] = new Conto(radice + activebankaccount , cf);
activebankaccount++;
}
you are using an uninitialized vale as index of the array bankaccount
I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx
I have the folowing interface;
public static interface Attributes
{
public final static String InterestDeterminationDate = "InterestDeterminationDate";
public final static String CreditType = "CreditType";
public final static String NumberInternal = "NumberInternal";
public final static String InterestRate = "InterestRate";
public final static String RemainingDebtAmount = "RemainingDebtAmount";
public final static String ConsumerPart = "ConsumerPart";
public final static String TechnicalProductName = "TechnicalProductName";
public final static String TermOfDuration = "TermOfDuration";
public final static String PeriodInterestTaxReduction = "PeriodInterestTaxReduction";
public final static String OriginMark = "OriginMark";
public final static String Currency = "Currency";
public final static String PenaltyRuleId = "PenaltyRuleId";
public final static String InstallmentCalculationMethod = "InstallmentCalculationMethod";
public final static String InterestRenewalDate = "InterestRenewalDate";
public final static String TechnicalProductDescription = "TechnicalProductDescription";
public final static String TechnicalProductDate = "TechnicalProductDate";
public final static String CollectionIntervalPeriod = "CollectionIntervalPeriod";
public final static String Enddate = "Enddate";
}
I need to check is a given string is a part of this Attributes Interface.
How can i check this?
Regards,
bas Hendriks
If you really want todo this, then you should use reflection and go through all the values in Attributes.
A better way to do this would be the use of enums :
public enum Attributes{
InterestDeterminationDate,
CreditType,
NumberInternal,
InterestRate,
RemainingDebtAmount,
ConsumerPart,
TechnicalProductName,
TermOfDuration,
PeriodInterestTaxReduction,
OriginMark,
Currency,
PenaltyRuleId,
InstallmentCalculationMethod,
InterestRenewalDate,
TechnicalProductDescription,
TechnicalProductDate,
CollectionIntervalPeriod,
Enddate;
}
and the Attributes.valueOf(yourVariable); would check this for you.
Beware with enum, the valueOf() method will throw a IllegalArgumentException if yourVariable isn't in Attributes. Plus you yourVariable isn't null or you will have to handle a NullPointerException
Your question doesn't make it clear whether you're trying to find out if the query string is the property name or value. If you're trying to find out if it's a value, the following will work:
public static boolean hasValue(String value) throws IllegalAccessException {
for(Field field : Attributes.class.getDeclaredFields()) {
if(((String)field.get(Attributes.class)).equals(value)) {
return true;
}
}
return false;
}
However, I would advise following Colin's suggestion of using an Enum, it will be easier for you to work with in the future.
You can build a set using reflection and test against that set:
Class<Attributes> attr = Attributes.class;
Field[] fields = attr.getDeclaredFields();
final Set<String> fieldsInAttributes = new HashSet<String>();
for (Field field : fields) {
fieldsInAttributes.add(field.getName());
}
System.out.println(fieldsInAttributes.contains("PenaltyRuleId"));
You can use the reflection API, and the "getFields()" method of the Class class.
Then you check the field name with the "getName()" method of the Field class.
Here is the Oracle official tutorial.
public static String getFieldName(String fieldValue) throws Exception {
for (Field field : Attributes.class.getFields())
if (fieldValue.equals(field.get(null)))
return field.getName();
return null;
}