So I just spent around an hour trying to unveil and resolve a very strange bug, one that I have never seen before.
I am more or less asking for potential causes of this seeming random cast from enum to String rather than "please fix my code for me".
The gist of the problem is as follows:
I have an interface, call it IFoo, within this interface, it has a static enum, called Bar:
public interface IFoo {
static enum Bar{
A,
B,
C,
}
Bar doGetBar();
}
I of course have a Foo class that implements IFoo.
public class Foo implements IFoo{
public Bar getBar(){
return Bar.A; // for example
}
}
Somewhere else, I have an object array called
Object[] result;
And a helper method that returns an array of Objects, holding results from the getBar()method, call it
public Object[] getBars()
Now, when I do
result = getBars();
result magically holds Strings instead of Bars, the values of the strings are the implementation class of the outer class (not really an outer class, more of a wrapper class?) of Bar, i.e. "Foo".
Could someone possibly explain to me how this is possible?
Some leads:
1. results were holding strings before the assignment.
2. the static enum inside IFoo is questionable, it was non-static, but it caused ClassCastExceptions when I tried to cast it to IFoo.Bar from Foo.Bar (or something along these lines).
Your Object[] has got Strings in it because you put them there. If you post a small example piece of code demonstrating clearly that you put Bars in but get Strings out I will be very surprised.
The method for resolving bugs like this is to start from the beginning, making a simple working example (which will likely not display the bug). Then keep adding code to make it more like your real-world application until the bug rears its head. Then you'll be able to identify your most recent change as the source of the bug.
It's not clear what "magic" is contained within the getBars() method, and without more information, It's not possible to produce a sample implementation to verify this behaviour. Specifically, it's not clear what "a helper method that returns an array of Objects, holding results from the getBar() method" means.
If you can, isolate the smallest test case containing the behaviour, as suggested. oxbow_lakes' suggestion is also good; bring a simple test as close to the real behaviour as possible.
If you really can't produce a simplified scenario to show us, then our ability to help you is going to be severely curtailed, since that getBar() method is where the Object[] is populated. In that case, if you can't work it out, then I suggest you may have to ask a more knowledgeable colleague for a bit of help - could be a second set of eyes will spot it.
Use collections and generics for type safety instead.
Edit As now the question changed to a conceptional level, I'll use my telesense to figure out the cause.
It seems you are reusing an Object[] array on line 252 for completely different purposes. The compiler accepts
Object[] objs = Bar.values();
//...
objs = "A B C".split("\\s+");
//...
return objs;
this kind of code because arrays in Java are covariant (e.g. String[] is subclass of Object[]). Reusing a base class object array this way is troublesome.
I am assuming that your getBars() method looks like this:
public Object[] getBars() {
return Bar.values();
}
if you are wondering what you should be receiving from the 'Bar.values()' method, check out the JavaDoc. In your case, values() would return type FooI$Bar.
It might be useful to post, not only the code that you have put together that throws the exception, but the ClassCastException as well.
Related
Not quite sure what the formal term for such a pattern/problem, but here is what I'm facing:
I have an operation that is somewhat large. It can either pass or fail. Each pass or fail carries with it either the result of the successful operation, or information about why the operation failed. I am struggling to architect this function 'correctly'.
class Pass{
int someGoodStuff;
double someOtherGoodStuff;
}
class Fail{
String failureMsg;
float howMuchOperationWasOffBy;
}
class Operator{
public ??? operation(){
}
}
Approach 1: Fail states are like exceptions. Lets throw them. This allows me to include the failure information and make the return type just Pass. However, these fail states are not programming language errors, they are business logic fails. So, two things sit wrong with me about this approach: one, it confuses business logic fails with actual Java errors (which seems wrong) and two, it coopts the normal flow of execution without any really good reason to do so.
Approach 2: Functions in java like to return one object type, so have Pass and Fail both implement an interface Result, and have the return type of the function be that.
interface Result{...}
class Pass implements Result{...}
class Fail implements Result{...}
class Operator{
public Result operation(){...}
}
However, the pass and fail states that the function returns are completely different. They have little to no overlapping variables or functions. This seems wrong and reduces me to have to instanceof all the important information out of the passes and fails.
Approach 3: Some sort of union object that can be either pass or fail (but not both)
class Result{
public Pass pass=null;
public Fail fail=null;
}
class Operator{
public Result operation(){...}
}
This has the advantage that I can say things like
Result result=op.operation();
if (result.succeed()){
doStuffWithPass(result.getPass());
}else{
doStuffWithFail(result.getFail());
}
Which is basically what I was doing with instanceof, but nicer looking; the code now looks how you might expect it to. It is clear to follow.
However, Java has no real Union types. I have to make sure someone doesn't accidentally try to mess with the pass variables of a fail Result or vice versa. Furthermore, every method I call on the union type have to be predicated with figuring out whether it is a pass or fail (That If branch suddenly has to be everywhere)
Finally, although not a real concern yet, such a pattern I believe allocates space for both a Pass and a Fail for each Result, when I know that it can only ever be one of them (ie it should take up a space equal to Max(space(Pass),space(Fail)))
None of these approaches seems perfect. I feel like there should be a pattern to solve this kind of problem. Is there?
In this case Error thrown Approach Seems to be best.
Reasons
You can create multiple Custom Exceptions for multiple type and when there is anything wrong happens. By this approach you make sure that whenever something bad happen your program returns the control with specified error.
As a return type you can return your Result with specific value. So whenever your program return something it seems working or pass.
This might be a trivial question, but I need some clarification...
There is a book called Clean Code that says that our methods should be small, preferably up to 5-10 lines long. In order to achieve that we need to split our methods into smaller ones.
For instance, we may have someMethod() shown below. Let's say, modification of 'Example' takes 5 lines and I decide to move it into a separate method, modify 'Example' there and return it back to someMethod(). By doing this, someMethod() becomes smaller and easier to read. That's good, but there is a thing called "side effects" which says that we shouldn't pass an object to another method and modify it there. At least, I was told that it's a bad idea ) But I haven't seen anything prohibiting me from doing so in Clean Code.
public Example someMethod() {
// ... different lines here
Example example = new Example();
example = doSomethingHere(example, param1, param2, ...);
// ... different lines here
return example;
}
private Example doSomethingHere(Example example, 'some additional params here') {
// ... modify example's fields here ...
return example;
}
So, am I allowed to split the methods this way or such a side effect is prohibited and instead I should deal with a rather long-line method that definitely breaks Clean Code's rules talking about short methods?
UPDATED (more specific name for the sub-method)
public Example someMethod() {
// ... different lines here
Example example = new Example();
example = setExampleFields(example, param1, param2, ...);
// ... different lines here
return example;
}
private Example setExampleFields(Example example, 'some additional params here') {
// ... modify example's fields here ...
return example;
}
As JB Nizet commented, it's not actually a side effect if it's the only effect, so any blanket statement that "all side effects are bad" doesn't apply here.
Still, the main question stands: Is this (side) effect okay?
Talking about the principles first, side effects are, in general, dangerous for two reasons:
they make concurrency more difficult
they obscure/hide information
In your example, there is some information that is hidden. You could call this a potential side effect, and it can be exposed with a question: "Does this doSomethingHere method create a new object or modify the one I pass in?"
The answer is important, and even more so if it's a public method.
The answer should be trivial to find by reading the doSomethingHere method, especially if you're keeping your methods 'clean', but the information is nonetheless hidden/obscured.
In this specific case, I would make doSomethingHere return void. That way there's no potential for people to think that you've created a new object.
This is just a personal approach - I'm sure that plenty of developers say you should return the object you modify.
Alternatively, you can pick a 'good' method name. "modifyExampleInPlace" or "changeSomeFieldsInPlace" are pretty safe names for your specific example, imo.
we shouldn't pass an object to another method and modify it there.
Who says that? That is actually a good practice in order to split your function in a way that forms a "recipe" and have specific functions that know exactly how to populate your object properly.
What is not recommended (and probably the source where you got your recommendation misunderstood this rule) is defining a public API and modify the arguments. Users appreciate not having their arguments modified as it leads to less surprises. An example of that is passing arrays as arguments to methods.
When you define an object and pass it to an other method, method itself can modify the content of the object therein which may be unwanted in some cases. This is because you pass the reference(shallow copy) of the object to that method and method can modify that object.For example when you pass an Array, Arrays are objects, to a method, method can change the content of the Array which may not be what the caller method expects.
public static void main(String[] args){
int[] arr= {1,2,3,4};
y(arr);
//After the method arr is changed
}
public void y(int[] comingArray){
comingArray[0] = 10;
}
To make sure the values of Array cannot be changed, deep copy of the Array should be sent to method which is another story
However this is not the case when you use primite types(int, float etc.)
public static void main(String[] args){
int a= 1
y(a);
//After the method a is not changed
}
public void y(int comingInt){
comingInt = 5;
}
Due to the nature of the Objects, you should be carefulTo learn more about shallow copy and deep copy https://www.cs.utexas.edu/~scottm/cs307/handouts/deepCopying.htm
I am trying to determine what the best practices would be for an ImmutableList. Below is a simplistic example that will help drive my questions:
Ex:
public ImmutableCollection<Foo> getFooOne(ImmutableList<Foo> fooInput){
//.. do some work
ImmutableList<Foo> fooOther = // something generated during the code
return fooOther;
}
public Collection<Foo> getFooTwo(List<Foo> fooInput){
//.. do some work
List<Foo> fooOther = // something generated during the code
return ImmutableList.copyOf(fooOther);
}
public void doSomethingOne(){
ImmutableCollection<Foo> myFoo = getFooOne(myList);
...
someOtherMethod(myFoo);
}
public void doSomethingTwo(){
Collection<Foo> myFoo = getFooOne(myList);
...
someOtherMethod(myFoo);
}
My Questions:
Which makes the most sense to use in an application? [doSomethingOne and getFooOne] or [doSomethingTwo and fooTwo]? In other words if you know you are using ImmutableCollections does it make sense to keep casting back and forth and doing copyOf(), or just use Immutable everywhere?
These examples are public methods which could imply that other people use them. Would any of these answers change if the methods were private and used internally?
If a user tries to add anything to an immutable List an exception will be thrown. Because they may not be aware of this, wouldn't it make more sense to explicitly return an ImmutableCollection instead of a Collection?
In general, it's wise not to commit to a specific implementation in your declared return type, but we think of the immutable types as an exception. There are a few reasons to declare a return type of Immutable*:
They document that you're returning a snapshot, not a live view.
They document that the caller can't mutate the result.
They document that insertion order is preserved (which may or may not be significant in your use case).
They document that the collection won't contain null.
Someone might want the asList() or reverse() method.
You may save someone a copyOf() call if he wishes to assign to an Immutable* field. (But note that, if he does include copyOf(), it will short-circuit for most immutable inputs, even if you don't declare the return type.)
Basically, I'm just cribbing from https://github.com/google/guava/wiki/TenThingsAboutImmutableCollections, which you may want to check out in its entirety.
If I understood your intentions, the proper way of designing getFooXxx for making an immutable copy of maybe-mutable-list is something like this:
/**
* Returns an <b>immutable copy</b> of input list.
*/
public ImmutableList<Foo> immutableCopyOfFoo(List<Foo> input){
return ImmutableList.copyOf(input);
}
Why?
ImmutableList.copyOf() does it's magic when given list is immutable,
method signature explicitly says what it does,
method returns ImmutableList which is, in fact, an ImmutableCollection but why would you like to hide information about ImmutableList from user? If he wants, he'll write Iterable foo = immutableCopyOfFoo(mutableFoo); instead, but 99% he'll use an ImmtableList,
returning an ImmutableList makes a promise - "I am immutable, and I will blow everything up if you try to change me!"
and last but not least - proposed method is unnecessary in internal use; just use
someOtherMethod(ImmutableList.copyOf(foo));
directly in your code...
You should check #ChrisPovirk's answer (and link to wiki in that answer) to know that i.e. when List<Foo> input contains nulls, you will get nasty NPE on runtime if you try to make an immutable copy...
EDIT answering comment #1:
Collection contract is less strict than List's one; i.e. Collection doesn't guarantee any order of elements ("Some are ordered and others unordered") while List does ("An ordered collection (also known as a sequence)").
If an input is a List it suggests that order is important and therefore output should guarantee the same. Imagine that:
public ImmutableCollection<Foo> immutableCopyOfFoo(List<Foo> input){
return ImmutableSortedSet.copyOf(input, someFancyComparator);
}
It doesn't smell right. If you don't care about order then maybe method signature should be immutableCopyOfFoo(Collection<Foo> input)? But it depends on concrete use case.
public ImmutableCollection<Foo> getFooOne(ImmutableList<Foo> fooInput){
ImmutableList<Foo> fooOther= fooInput;
return ImmutableList.copyOf(fooOther);
}
This makes no sense at all. Why would you ever copy an immutable collection? The whole point of immutability is: it can't be changed, so you might as well re-use it.
public Collection<Foo> getFooTwo(List<Foo> fooInput){
ImmutableList<Foo> fooOther= ImmutableList.copyOf(fooInput);
return ImmutableList.copyOf(fooOther);
}
??? Why do it twice??? This is fine:
public Collection<Foo> getFooTwo(List<Foo> fooInput){
return ImmutableList.copyOf(fooInput);
}
ImmutableList.copyOf(Collection) is smart enough to return ImmutableList unmodified and create a new ImmutableList for everything else.
My usual approach is:
accept List for parameters (so the interface is easier to use for clients)
if performance/memory usage/thread-safety is important, copy the contents of the provided List into a data structure that is optimized for usage by your class
when returning an ImmutableList, ImmutableList should be the return type (because it gives the caller more information about how it can use the returned value)
when returning a mutable implementation of List, List should be the return type, unless something else about the return type is important (thread-safety, as a bad* example)
* It's a bad example because if your return values need to be thread-safe, it probably means something else is wrong with your code.
Replace List/ImmutableList with any of the immutable collection types.
You should always use the standard JRE classes on public interfaces. There are no extra methods on Guava's Immutable... classes so you're not gaining any compile-time safety: any attempts to make changes to those objects will only fail at run-time (but see Bart's comment). You should document in methods that return collections that they're immutable.
You should make defensive copies of lists provided on public methods if you're worried about concurrent modification, but it's OK to specify ImmutableCollection on private method arguments.
This might seem to be a strange question: I am struggling to decide whether it is a good practice and "efficient" to work with "Typed Objects" on a very granular level.
public Object[] doSomething() {
Object[] resultList = new Object[] {new Foo(), new Bar()};
return resultList;
}
versus
public Result doSomething() {
Result result = new Result();
result.foo = new Foo();
result.bar = new Bar();
return result;
}
public class Result{
Foo foo;
Bar bar;
}
My question is concrete as follows:
In terms of CPU Cycles (as a relative figure), how much does the second approach consume more resources. (like 100% more)
The same question in regard to memory consumption
NB (these two are questions to understand it more, its not about premature optimization)
In terms of "good design practice". Do you think version 1 is an absolute No-Go or do you rather think it actually does not matter...Or would you propose never returning "object Arrays" (((in an object oriented programming language)))...
This is something, I am always wondering if I should create dedicated Objects for everything (for passing values) or I should rather use generic objects (and common method parameters...)
The question also applies to
public doSomething(Query query )
versus
public doSomething(Foo foo, Bar bar, Aaaa, a, Bbbbb)
thanks
Markus
3.) In terms of "good design pratice". Do you think version 1 is an absolute No-Go or do you rather think it actually does not matter...Or would you propose never returnung "object Arrays" (((in an object oriented programming langauge/regarding encapsulation ...)))...
Version 1 is absolutely a no-go. It's almost completely untyped. The caller has to know the actual types and where they are in the array, and cast appropriately. You lose any useful compile-time type checking, and the code itself is significantly less clear.
I would never return an Object[] unless the values it contained were constructed with new Object().
I don't believe that defining a Result class and returning that consumes any more resources at run time than constructing an Object[]. (Granted, there's a miniscule cost for storing and loading the class definition.) Do you have data that indicate otherwise?
Returning an untyped object array is poor practice for various reasons, among which are:
It's prone to error.
It's harder to maintain.
Casting back to the "real" type is not free, either.
Regarding your other query:
public doSomething(Query query)
versus
public doSomething(Foo foo, Bar bar)
This is less clear-cut. If packaging up a Foo and a Bar into a Query object makes sense in the problem domain, then I would definitely do it. If it's just a packaging up for the sake of minimizing the number of arguments (that is, there's no "query object" concept in your problem domain), then I would probably not do it. If it's a question of run-time performance, then the answer is (as always) to profile.
I'd have to do an experiment to really know, but I'd guess that the object array would not be significantly faster. It might even be slower. After all, in either case you have to create an object: either the array object or the Result object. With the Result object you have to read the class definition from disk the first time you use it, and the class definition has to float around in memory, so there'd be some extra cost there. But with the array object you have to do casts when you pull the data out, and the JVM has to do bounds checkings on the array (What happens if the caller tries to retrieve resultList[12]?), which also involves extra work. My guess is that if you do it only once or twice, the array would be faster (because of the class load time), but if you do it many times, the dedicated object would be faster (because of the cast and array access time). But I admit I'm just guessing.
In any case, even if the array does have a slight performance edge, the loss in readability and maintainability of the code almost surely isn't worth it.
The absolute worst thing that can happen is if values you're returning in the array are of the same class but have different semantic meanings. Like suppose you did this:
public Object[] getCustomerData(int customerid)
{
String customerName=... however you get it ...
BigDecimal currentDue=...
BigDecimal pastDue=...
return new Object[] {customerName, pastDue, currentDue};
}
... meanwhile, back at the ranch ...
Object[] customerData=getCustomerData(customerid);
BigDecimal pastDue=(BigDecimal)customerData[2];
if (pastDue>0)
sendNastyCollectionLetter();
Do you see the error? I retrieve entry #2 as pastDue when it's supposed to be #1. You could easily imagine this happenning if a programmer in a moment of thoughtlessness counted the fields starting from one instead of zero. Or in a long list if he miscounted and said #14 when it's really #15. As both have the same data type, this will compile and run just fine. But we'll be sending inappropriate collection letters to customers who are not over due. This would be very bad for customer relations.
Okay, maybe this is a bad example -- I just pulled it off the top of my head -- because we would be likely to catch that in testing. But what if the values we switched were rarely used, so that no one thought to include a test scenario for them. Or their effect was subtle, so that an error might slip through testing. For that matter, maybe you wouldn't catch this one in testing if you were rushing a change through, or if the tester slipped up, etc etc.
In a software development class at my university, the teacher kept mentioning that on a quiz we needed to make sure that a field returned by a getter needed to be "protected." I guess she meant that nothing outside the class should be able to change it. She didn't give much more of an explanation than that.
For instance:
class Foo {
string[] bar = <some array contents>;
public string[] getBar() {
return bar;
}
}
Any code calling getBar would be able to modify the elements in that array. How do you prevent that from happening? I'm assuming that the object itself should be able to modify the array, just not anything outside the object.
This isn't homework help since the quiz is a couple of weeks old. I simply want to understand Java better since my teacher didn't explain very well.
Update: The teacher wouldn't merely allow us to use protected as the access modifier on the field.
You either use a collection and wrap it in Collections.unmodifiable*() or you defensively copy your array, collection or object if its mutable (which arrays always are).
For example:
class Foo {
private String[] bar = <some array contents>;
public String[] getBar() {
return bar == null ? bar : Arrays.copyOf(bar);
}
}
What you have to watch out for is that this is a shallow copy (so is clone). Not sure what your teacher's problem with clone was.
Just to add to one of the previous answers, you want to make sure that with a collection you aren't using the clone() method to achieve what you are trying to achieve here. This creates a shallow copy of the collection only, all object references contained in the collection copy still point to the same objects as in the original, e.g. the objects in the collection copy can still be modified, even though the original collection cannot. Be sure you are making a deep copy of a returned collection if this is what you are trying to do.
I suspect what she meant was that the visibility of the field itself should be protected (or private) so that access only occurs through the getter. In the case of a collection, you may also want to do as #cletus suggests and return a copy of the collection if you don't want it to be modified outside the class. EDIT Based on your edit, she probably meant both.
class Foo {
protected string[] bar = <some array contents>;
public string[] getBar() {
return bar;
}
}
To protect that field from being changed you need to first make it private and don't provide any setter of any other method which changes that field. This way nobody can change the reference of that variable.
If the field is a mutable Object then again its value can be changed. For that you would need to do deep cloning before returning that object.
I'd add to cletus' first suggestion - the easiest way of making bar immutable would be to use a List instead of an array and return it wrapped in an unmodifiableList. That way it's immediately clear to the client of the class that the contents of bar can't be altered - an UnsupportedOperationException is thrown. Messing about with deep cloning will probably be pretty inefficient, depending on the complexity of your objects, and still returns a bunch of mutable objects - it's just that any changes made to those will be ignored by Foo.
class Foo {
private List<String> bar = new ArrayList<String>();
public Collection<String> getBar() {
return Collection.unmodifiableList(bar);
}
}
(Also might be worth noting that with generics in Java 5+, a list behaves much more like an array than it used to).
Please tell the professor that all non-final fields must be private to preserve encapsulation.
Protected allows your subclass or other classes in the same package to modify the field without your class knowing it.
The only class that should touch non-final fields directly is the class that defines them.
(Think about what would happen if you wanted to later fire an event when the field changes... you can only do that if all access is through the setter...)