How to get protected value out of one class and into another - java

I have two public classes, VAG.java and XY.java. Inside VAG there's a protected value I would very much like, nay, I need to have in XY. All attempts thus far have failed. From inside XY
List<Double> val = VAG.valOfConcern;
yields java.lang.NullPointerException, calling
public List<Double> getVal( ) {
return valOfConcern;
}
on my VAG object yields the same. Now I know what you're thinking; spoof, it's because the object is null, has it been initialized? It has, but maybe that particular variable hasn't been initialized yet? I'm not sure how to ask for help without just posting both full files (~1500 lines) and who's going to want to look through that anyway?
I need a wormhole, is there such a thing? Some hacky way where I can pull off some shared memory type thing in Java? I'm at my wits end, I'm about to start writing the value to a '.txt' and reading it off.
Thank you for listening to me ramble, feel free to tear me a new one, I'm frustrated.

Related

Class enumeration cannot be used in method logic - not sure what the issue is, or how to figure it out

As part of an assignment for school, I'm making checkers. I was trying to figure out the best way to set the type of piece (normal/king+color), and enums seemed to be the proper tool for such a thing, but I can't figure out how to use them effectively, and the reading I'm doing on enums isn't helping me to solve the issue I have with my code. In the class Checker I have this so far:
enum Type {RED_NORM, RED_KING, BLACK_NORM, BLACK_KING}
public Class Checker {
int posRow;
int posCol;
Type checkerType;
public Checker(...)
{...}
public int[] posCheck()
{...}
public boolean kingCheck()
{
boolean isKing = false;
if(checkerType == RED_NORM)
{
if (posRow == 10)
checkerType = RED_KING;
}
else if(checkerType = BLACK_NORM)
if (posCol == 0)
checkerType = BLACK_KING;
return isKing;
}
}
This doesn't work, obviously, but I'm not really sure what I'm doing wrong (and I can't figure out what exactly it is that I need to google). RED_NORM, RED_KING, etc. all say they cannot be resolved to a variable. I'm not sure why this doesn't work, considering the constructor is able to refer to the checkerType variable just fine (I think)? the only errors Eclipse is displaying is with the RED_NORM, RED_KING, etc in the kingCheck method.
I'm having a hard time understanding the things I'm reading when I'm trying to google this (and, as i said, a hard time syntaxing my search properly). Any help would be appreciated - apologies in advance for what seems to be a moronic question.
Instead of directly referencing RED_NORM, RED_KING, BLACK_NORM, BLACK_KING, reference it like this :
Type.RED_NORM, Type.RED_KING etc..
When you reference it directly, the system thinks that you are referring to a variable instead of a value. You have to specify the type of value that you are using.
P.S. Whatever you want to look up, start with the simplest words, just google Java enums and you should find what you are looking for with a little bit of research. For more help, you can visit this URL.
Hope this helps.

Java ArrayList issue

I need some help with a line of code in a program that I am writing. I feel like it's going to be some stupid mistake but I just can't seem to figure out what it is...
ArrayList<Integer> knockSequence; //Default knockSequence
ArrayList<ArrayList<Integer>> customSequences; //used to store custom sequences for client after first connection
ArrayList<ServerClient> connectedClients; //List of connected clients
//...
public void giveNewSequence(ArrayList<Integer> newSequence, ServerClient client) //client MUST be in connectedClients in order for this to work
{
customSequences.get(connectedClients.indexOf(client)) = newSequence;
}
Why won't the line "customSequences.get(......." work? The error I'm getting is saying that it is looking for a variable but a value is being found. Any feedback is appreciated
Why won't the line "customSequences.get(......." work?
You're trying to assign a value to the result of a method call. That's what doesn't work. You can only use the assignment operator with a variable.
I suspect you want:
customSequences.set(connectedClients.indexOf(client), newSequence);
You should also consider using a single collection with a composite type which contains the knock, custom sequence and connected client, rather than managing three separate collections where the values are related by index (which is what I suspect you've got here). You might want to use a map as well, rather than a list.

Using an unsupported library, leading me onto casting

I have to work with this library that deals with a standard for biodiversity. Essentially, it reads in csv, xml etc and validates it, allowing one to iterate through the records with the type DarwinCoreRecord
For some odd reason, as soon as the object is moved from the iterator, it is gone. Small example below:
ArrayList<DarwinCoreRecord> dwc = new ArrayList<DarwinCoreRecord>();
for(; iter.hasNext();) {
DarwinCoreRecord record = iter.next();
System.out.println(record.getSomeValue());
dwc.add(record);
}
That print statement is perfect and prints out the right details, if I out that print statement outside of the for loop, nulls are had by all.
So, onto my question (unless anyone can solve the above). I created a skeleton class that extends this DarwinCoreRecord. It looks exactly like this:
public class DWCRecordStore extends DarwinCoreRecord {
public DWCRecordStore() {
}
}
This was just to test my plan would work but I am getting a classcastexception. It has been a while since I have dealt with casting (in Java, at least) but I see no issues. I am not casting from DWCRecordStore to DarwinCoreRecord so I cannot see the problem.
Does anyone see anything glaring that I have missed?
Thanks in advance.
EDIT: Sorry, error is here:
java.lang.ClassCastException: org.gbif.dwc.record.DarwinCoreRecord cannot be cast to com.encima.DWCRecordStore
at com.encima.DroolsTest.main(DroolsTest.java:37)
EDIT 2: Added my use of the casting.
DWCRecordStore drs = new DWCRecordStore();
DarwinCoreRecord dwc = iter.next();
drs = (DWCRecordStore) dwc;
You are trying to cast DarwinCoreRecord into an DWCRecordStore - but the first is not an instance of the second!
Think of DarwinCoreRecord as a polygon and DWCRecordStore as a square, you can always cast a square (DWCRecordStore) to a polygon (DarwinCoreRecord) - but not the other way around.
It might be that you are trying to store an object that was returned from the lobrary as a DWCRecordStore. But the library is unfamiliar with DWCRecordStore, it returns only DarwinCoreRecord objects, which are not DWCRecordStore.
Pinpointing the exact problem might require more code - how exactly did you use your new class.
EDIT: your last edit clarifies it, since dwc is not instance of DWCRecordStore, it cannot be casted to one.
An alternative might be creating a constructor: DWCRecordStore(DarwinCoreRecord), and using:
drs = new DWCRecordStore(dwc);

Setting Hashmap in a loop

I have the following code:
Map<String, ObjectType> objectMap = new HashMap<String, ObjectType>();
for (ObjectType obj : objects) {
obj.setSomeProperty("property value");
objectMap.put(obj.getADiffProperty(), obj);
}
It seems like during loop iteration some of the obj property changes for different keys than the one currently being set. Is there a problem with the above code? Somehow the reference to obj is being recycled by the for loop?
Also this loop is in an outer loop as well.
Update:
I am providing the full method below. The actual place where I am observing the behavior described above is in the outer map defined as Map<String, Map<String, GlossaryTerm>> loadedTerms = new HashMap<String, Map<String, GlossaryTerm>>(); defined in a Singleton class.
List<Audience> audiences = ContentAccess.getAudienceList();
List<GlossaryTerm> glossaryTerms = ContentAccess.getAllReplacementCIs();
for (Audience audience : audiences) {
Map<String, GlossaryTerm> termMap = new HashMap<String, GlossaryTerm>();
for (GlossaryTerm term : glossaryTerms) {
String definition = term.getProductGlossary().get(audience.getName());
if (definition != null)
term.setDefinition(definition);
termMap.put(term.getPhrase(), term);
}
loadedTerms.put(audience.getChannelId(), termMap);
}
I don't think what you think is happening, is happening. The object reference is what it's supposed to be, for each iteration. I think something else must be happening - that the properties are changing elsewhere, or don't have the values you think they have initially. Put in some printlns to track down what's really going on. The code you've shown can't be changing the wrong properties.
It seems like during loop iteration some of the obj property changes for different keys than the one currently being set. Is there a problem with the above code? Somehow the reference to obj is being recycled by the for loop?
The obj variable will be set to the "next" element of the iterator for objects each time around the loop. If you see the same reference value in obj more than once it can only be because:
the reference value genuinely appears more than once in collection, array or whatever given by objects, or
something in setSomeProperty or getADiffProperty or something else you are doing in the loop is updating objects as a side-effect, or
the objects object has a buggy iterator implementation.
Another possibility is that what you are seeing is different objects with the same adiff values.
To say anything more, I'd need to see more source-code than the simplified snippet you have provided.
EDIT - the extra code you provided has not revealed the problem. (I think we can dismiss any theories involving updating the lists while they are being iterated, or strange side-effects from the setters.)
My suspicion is that one of those lists that the singleton is providing contains duplicates or something else unexpected. It could be that is what is causing your problem.
Do what #Carl suggests and use traceprints and/or a debugger to figure out what is in the Collection singleton and what your code is actually doing.
EDIT 2 - The fact that the collection thingy is a singleton class is probably irrelevant. And the contents of a HashMap DO NOT change randomly or spontaneously. (And there are no little green demons in your code that conspire to make it fail. Trust me on this!)
You seem to have the mindsight of guessing what the problem is and making changes based on those guesses in the hope that they will fix the problem. STOP GUESSING! That is the wrong approach, and will probably only make things worse. What you need to do is debug the code carefully and methodically, gathering hard evidence of what your program is actually doing, and interpreting that evidence carefully ... without resorting to crazy notions that something is changing things randomly.
EDIT 3 - If I was in your situation, I would ask another experienced Java programmer in the team to sit down with me and help me debug the code. I still occasionally need to do this myself, and I've had 10 years+ Java experience and 30+ years programming experience. Sometimes you get a mental block on a problem, and a fresh mind / fresh approach is the answer.
It is not a shameful thing to admit to your team / boss that you are out of your depth and need help.
I'm starting a new answer because - well, it's a new thought here, and the discussion thread was getting rather long.
You haven't (I think) said when the changes happen. But you are (potentially) putting the same term into multiple maps, for different audiences. Nothing to do with the loop variable - just that you are repeatedly using the same list of terms, for each audience. But when you put the term into a map, you also change its definition. But the definition is (potentially) different for each audience. So, concrete example:
Term A has the definition of "x" for audience X, and "y" for audience Y. You have both audiences. Initially, we encounter audience X, so A gets definition "x". A gets added to the map for this audience. Now we iterate to the next audience, and change the definition for A to "y". This changes A everywhere you have a reference to it - including in the map for audience X. This would explain why making a copy eliminates the problem. Is this what you are experiencing?
This might be just a typo error. There is no object declared in your snippet, but your put call uses object.getADiffProperty() rather than obj.getADiffProperty(). Is that intentional?
From where the code is called? May be there are concurrent issues? Are there other threads (is it a webapp?) accessing ContentAccess? And I hope GlossaryTerm is a simple Dto, right?

Should I keep instance variables in Java always initialized or not?

I recently started a new project and I'm trying to keep my instance variables always initialized to some value, so none of them is at any time null. Small example below:
public class ItemManager {
ItemMaster itemMaster;
List<ItemComponentManager> components;
ItemManager() {
itemMaster = new ItemMaster();
components = new ArrayList<ItemComponentManager>();
}
...
}
The point is mainly to avoid the tedious checking for null before using an instance variable somewhere in the code. So far, it's working good and you mostly don't need the null-value as you can check also for empty string or empty list, etc. I'm not using this approach for method scoped variables as their scope is very limited and so doesn't affect other parts of the code.
This all is kind of experimental, so I'd like to know if this approach could work or if there are some pitfalls which I'm not seeing yet. Is it generally a good idea to keep instance variables initialized?
I usually treat an empty collection and a null collection as two separate things:
An empty collection implies that I know there are zero items available. A null collection will tell me that I don't know the state of the collection, which is a different thing.
So I really do not think it's an either/or. And I would declare the variable final if I initialize them in the constructor. If you declare it final it becomes very clear to the reader that this collection cannot be null.
First and foremost, all non-final instance variables must be declared private if you want to retain control!
Consider lazy instantiation as well -- this also avoids "bad state" but only initializes upon use:
class Foo {
private List<X> stuff;
public void add(X x) {
if (stuff == null)
stuff = new ArrayList<X>();
stuff.add(x);
}
public List<X> getStuff() {
if (stuff == null)
return Collections.emptyList();
return Collections.unmodifiableList(stuff);
}
}
(Note the use of Collections.unmodifiableList -- unless you really want a caller to be able to add/remove from your list, you should make it immutable)
Think about how many instances of the object in question will be created. If there are many, and you always create the lists (and might end up with many empty lists), you could be creating many more objects than you need.
Other than that, it's really a matter of taste and if you can have meaningful values when you construct.
If you're working with a DI/IOC, you want the framework to do the work for you (though you could do it through constructor injection; I prefer setters)
-- Scott
I would say that is totally fine - just as long as you remember that you have "empty" placeholder values there and not real data.
Keeping them null has the advantage of forcing you to deal with them - otherwise the program crashes. If you create empty objects, but forget them you get undefined results.
And just to comment on the defencive coding - If you are the one creating the objects and are never setting them null, there is no need to check for null every time. If for some reason you get null value, then you know something has gone catastrophically wrong and the program should crash anyway.
I would make them final if possible. Then they have to be initialized in the constructor and cannot become null.
You should also make them private in any case, to prevent other classes from assigning null to them. If you can check that null is never assigned in your class then the approach will work.
I have come across some cases where this causes problems.
During deserialization, some frameworks will not call the constructor, I don't know how or why they choose to do this but it happens. This can result in your values being null. I have also come across the case where the constructor is called but for some reason member variables are not initialized.
In actual fact I'd use the following code instead of yours:
public class ItemManager {
ItemMaster itemMaster = new ItemMaster();
List<ItemComponentManager> components = new ArrayList<ItemComponentManager>();
ItemManager() {
...
}
...
}
The way I deal with any variable I declare is to decide if it will change over the lifetime of the object (or class if it is static). If the answer is "no" then I make it final.
Making it final forces you to give it a value when the object is created... personally I would do the following unless I knew that I would be changing what the point at:
private final ItemMaster itemMaster;
private final List components;
// instance initialization block - happens at construction time
{
itemMaster = new ItemMaster();
components = new ArrayList();
}
The way your code is right now you must check for null all the time because you didn't mark the variables as private (which means that any class in the same package can change the values to null).
Yes, it is very good idea to initialize all class variables in the constructor.
The point is mainly to avoid the
tedious checking for null before using
a class variable somewhere in the
code.
You still have to check for null. Third party libraries and even the Java API will sometimes return null.
Also, instantiating an object that may never be used is wasteful, but that would depend on the design of your class.
An object should be 100% ready for use after it's constructed. Users should not have to be checking for nulls. Defensive programming is the way to go - keep the checks.
In the interest of DRY, you can put the checks in the setters and simply have the constructor call them. That way you don't code the checks twice.
If it's all your code and you want to set that convention, it should be a nice thing to have. I agree with Paul's comment, though, that nothing prevents some errant code from accidentally setting one of your class variables to null. As a general rule, I always check for null. Yeah, it's a PITA, but defensive coding can be a good thing.
From the name of the class "ItemManager", ItemManager sounds like a singleton in some app. If so you should investigate and really, really, know Dependency Injection. Use something like Spring ( http://www.springsource.org/ ) to create and inject the list of ItemComponentManagers into ItemManager.
Without DI, Initialization by hand in serious apps is a nightmare to debug and connecting up various "manager" classes to make narrow tests is hell.
Use DI always (even when constructing tests). For data objects, create a get() method that creates the list if it doesn't exist. However if the object is complex, almost certainly will find your life better using the Factory or Builder pattern and have the F/B set the member variables as needed.
What happens if in one of your methods you set
itemMaster = null;
or you return a reference to the ItemManager to some other class and it sets itemMaster as null.
(You can guard against this easily return a clone of your ItemManager etc)
I would keep the checks as this is possible.

Categories