How do I pass a constructor parameter to another object? - java

I hope this illustration will make my question clear:
class someThread extends Thread{
private int num;
public Testing tobj = new Testing(num); //How can I pass the value from the constructor here?
public someThread(int num){
this.num=num;
}
void someMethod(){
someThread st = new someThread(num);
st.tobj.print(); //so that I can do this
}
}

For one thing, having a public field is a bad idea to start with IMO. (Your names aren't ideal either...)
All you need to do is initialize it in the constructor instead of inline:
private int num;
private final Testing tobj;
public someThread(int num) {
this.num = num;
tobj = new Testing(num);
}
(You don't have to make it final - I just prefer to make variables final when I can...)
Of course, if you don't need num for anything else, you don't need it as a field at all:
private final Testing tobj;
public someThread(int num) {
tobj = new Testing(num);
}

Why not just initialize your object in the constructor ??
public Testing tobj ; //How can I pass the value from the constructor here?
public someThread(int num){
this.num=num;
tobj = new Testing(this.num);
}

Related

Understanding reflection's strange behavior

I was writing this piece of code to understand reflection and encountered one scenario where I couldn't really figure out the reason for the codes' behavior. Hopefully I receive some guidance from the community.
Following is my test model class & here, for every instantiation, I want to know the exact number of instances created during runtime (using reflection)
public final class Model {
private static final Model instance = new Model("Testing");
private static int count = 0;
private String name;
private Model(String name) {
this.name = name;
++count;
}
public static Model getInstance() {
return instance;
}
public static int getInstanceCount() {
return count;
}
public String getName() {
return name;
}
public void doSomething() {
try {
System.out.println("Shh.... I am trying to do something");
Thread.sleep(1000);
System.out.println("Ok! Done.");
return;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Oops! I failed in doing your job...");
}
}
The driver code for this scenario is as follows,
public class ReflectionTest {
public static void main(String[] args) throws Exception {
Model.getInstance().doSomething();
System.out.println(Model.getInstanceCount());
Constructor<?>[] constructor = Model.class.getDeclaredConstructors();
for (Constructor<?> aConstructor : constructor) {
aConstructor.setAccessible(true);
Model m = (Model) aConstructor.newInstance("Testing through Reflection");
System.out.println(m.getName());
m.doSomething();
System.out.println(m.getInstanceCount());
//System.out.println(Model.getInstanceCount());
}
}
}
The output for this above piece of code came out to be as follows,
Shh.... I am trying to do something
Ok! Done.
0
Testing through Reflection
Shh.... I am trying to do something
Ok! Done.
1
As you can see, the instance count came out to be 1. I expected it to be as 2.
However, I changed the test model class's constructor as shown below. The datatype of count is now changed to Integer, instead of previously set 'int'.
private Model(String name) {
this.name = name;
if (count == null)
count = 0;
++count;
}
Surprisingly, I get the correct value for the instance count.
Shh.... I am trying to do something
Ok! Done.
1
Testing through Reflection
Shh.... I am trying to do something
Ok! Done.
2
This might be a silly question, but I am not able to ponder on what really happened behind the scenes. I need some guidance from the community on this.
Thanks in advance.
This has nothing to do with reflection.
private static final Model instance = new Model("Testing");
private static int count = 0;
The initializers are executed in order. So:
private static final Model instance = new Model("Testing");
Executing the constructor causes count to be incremented from 0 to 1, but then:
private static int count = 0;
Sets count back to zero.
Reverse the order of the declarations.
private static int count = 0;
private static final Model instance = new Model("Testing");
Or omit the initializer on count (its default value is zero anyway).
private static final Model instance = new Model("Testing");
private static int count;

Java - Custom type nested in class

I am once again asking for technical support.
I need to define a custom type inside a class, I've done it like this:
public class MainClass {
private class CustomType {
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
private CustomType[] myArray;
public MainClass() {
myArray = new CustomType[1024]
System.out.println(this.CustomType[0].varB);
}
}
When I run it throws a NullPointerException at System.out.println(this.CustomType[0].varB);
I've tested if myArray gets properly initialized with 1024 elements and it does, however I can't seem to access them.
I just moved from C++ to Java so I'm still getting used to it, am I missing something blatant?.
You only create an array without any objects, so this.CustomType[0] is null.
You should add the objects to the array:
public MainClass() {
myArray = new CustomType[1024]
for (int i =0; i<myArray.length;i++ {
myArray[i] = new CustomType();
}
System.out.println(this.myArray[0].varB);
}
Also you should make the member of CustomType private and access it via getter and setter.
Two things,
You must instantiate CustomType.
CustomType does not need access to MainClass.this so you can make it static.
So
public class MainClass {
private static class CustomType {
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
private CustomType[] myArray;
public MainClass() {
myArray = new CustomType[1024];
for (int i = 0; i < myArray.length; ++i) {
this.CustomType[i] = new CustomType();
}
// Or
Arrays.setAll(myArray, CustomType::new);
System.out.println(this.CustomType[0].varB);
}
}
Not making it static stores a MainClass.this in every CustomType instance which is unnecessary overhead.
Arrays in java are objects. The following line of the code you posted creates an array of 1024 elements where each and every element is null.
myArray = new CustomType[1024];
If you want to place actual objects in the array, named myArray, you need to create instances of class CustomType and assign them to elements of the array, for example:
CustomType instance = new CustomType();
myArray[0] = instance;
Then you can execute the following line of code and it will not throw NullPointerException.
System.out.println(myArray[0].varB);
Here is the full code to get the value of varB. In which you can avoid declaring CustomType[] myArray
public class Test
{
private static class CustomType
{
public byte[] varA;
public int varB;
public CustomType() {
varA = new byte[3];
varB = 13;
}
}
public static void main(String... args)
{
System.out.println(new CustomType().varB);
}
}
The solution is to add some elements to that array. See the below steps for more information.
constructor will be invoked, when you create the object of that class
And then you created an empty array of CustomType with size 1024 and trying to access the first element which does not exist(default is null) and trying to perform operations on that null reference. So you are getting the NullPointerException.

Syntax error, telling me it wants ; and several other things

Just trying to run through some code for an assignment I'm doing. It is probably simple but for the life of me I can't figure out why I get the above error at the first line
(public WaterLog.......).
Later I want to pass it this line:
[ log = new WaterLog(8, damCapacity); ]
Any help would be appreciated, I am new to this sorry.
public class WaterLog(Integer windowSize, Integer maxEntry) {
private Integer size = windowSize;
private Integer max = maxEntry;
private ArrayList theLog(int windowSize);
private int counter = 0;
public void addEntry(Integer newEntry) throws SimulationException {
theLog.add(0, newEntry);
counter++;
}
public Integer getEntry(Integer index) throws SimulationException {
If (thelog.isEmpty() || thelog.size() < index) {
return null;
}
return thelog.get(index);
}
public Integer variation() throws SimulationException {
int old, recent = 0;
recent = thelog.get(0);
old = thelog.get(thelog.size-1);
return recent-old;
}
public Integer numEntries() {
return counter;
}
}
Assuming SimulationException is defined correctly:
class WaterLog{
private Integer size;
private Integer max ;
private ArrayList<Integer> theLog; //parameterize your lists
private int counter = 0;
public WaterLog(Integer windowSize, Integer maxEntry) //this is the behavior you were looking for
{
this.size = windowSize;
this.max = maxEntry;
theLog = new ArrayList<Integer>(windowSize);
}
public void addEntry(Integer newEntry) throws SimulationException {
theLog.add(0, newEntry);
counter++;
}
public Integer getEntry(Integer index) throws SimulationException {
if (theLog.isEmpty() || theLog.size() < index) { //Java is case sensitive
return null;
}
return theLog.get(index);
}
public Integer variation() throws SimulationException {
int old, recent = 0;
recent = theLog.get(0);
old = theLog.get(theLog.size()-1); //again, watch case, also size is a method
return recent-old;
}
public Integer numEntries() {
return counter;
}
}
See the comments I added.
EDIT: To explain a bit further what was going on, let's take a look at what you were doing.
public class WaterLog(Integer windowSize, Integer maxEntry) {
private Integer size = windowSize;
private Integer max = maxEntry;
private ArrayList theLog(int windowSize);
private int counter = 0;
You seem to have confused a class with a constructor. The variables you defined were attributes, which was correct. You needed to use the syntax I showed in my answer to create a constructor. For that same reason, you don't have access to variables like windowSize. To remedy this, we allow them to still be defined outside the constructor, but assigned values inside it, where we have access to windowSize and maxEntry.
If you want to pass some parameters to this class you need a constructor. By default Each and EVERY class comes with a default constructor - which is there, you just don't see it ( but can declare it). What you can then do is make an overloaded construcotr ( which takes some arguments ) and this is what you want so..
if you have a class
class WaterLog {
// no constructor
}
the above is really a
class WaterLog {
public WaterLog() {
// this is the constructor - if you do not declare it its still here, you just dont see it. Ofcourse you have option to declare it.
}
}
The overloaded constructor is something like this
class WaterLog {
public WaterLog() {
//default constructor
}
public WaterLog(Integer int, String string, etc...) {
//overloaded constructor
}
}
and the above is what you need in order to pass arguments to this class constructor. I am not briliant at explaining things but if you need more clarification just let me know :)

cannot find symbol symbol: method location: class

Sorry, just learning Java; but, can someone tell me why I'm getting a "cannot find symbol" error?
My code is as follows:
public class NumberHolder {
public int anInt;
public float aFloat;
public NumberHolder(int setAnInt, float setAFloat) {
setAnInt = anInt;
setAFloat = aFloat;
}
public static void main(String[] args) {
NumberHolder newNumber = NumberHolder(12, 24F);
}
}
Looks like you're missing a new before the call to the constructor:
NumberHolder newNumber = new NumberHolder(12, 24F);
EDIT:
Also, as Tassos Bassoukos points out in his answer, you need to turn around the assignments in the constructor:
anInt = setAnInt;
aFloat = setAFloat;
Although personally, I like to write my constructors like this:
public NumberHolder(int anInt, float aFloat) {
this.anInt = anInt;
this.aFloat = aFloat;
}
This is a matter of style and personal preference, though.
Since
public NumberHolder(int anInt, float aFloat);
is a constructor and not an ordenary method, you need to use the keyword new in order to obtain the actual object. You are calling it like a method and you don't have any method named NumberHolder (but it would be valid if you'd have)
Beyond the new keyword that you're missing, the assignment in the constructor should be the other way around.
You need to instanciate new objects with the new keyword.
public class NumberHolder {
public int anInt;
public float aFloat;
public NumberHolder(int anInt, float aFloat) {
this.anInt = anInt;
this.aFloat = aFloat;
}
public static void main(String[] args) {
NumberHolder newNumber = new NumberHolder(12, 24F);
}
}

java - an enum question

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

Categories