Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Sedro
Dec 31, 2008

fletcher posted:

At any rate, can somebody rip apart my method and tell me why it sucks?
I don't see anything terribly wrong with your logic, although I had to look up the behavior of ArrayUtils.subarray when end > length. However your algorithm is fundamentally different than guava's because guava is lazy:

quote:

The inner lists are sublist views of the original list, produced on demand using List.subList(int, int), and are subject to all the usual caveats about modification as explained in that API.

Adbot
ADBOT LOVES YOU

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

fletcher posted:

Is there anything wrong with this? I haven't used generics much, and I get an 'unchecked cast' warning, so I wasn't sure if I was going about this the right way.
I'm assuming you're getting an "unchecked cast" warning on the subarray line, since its return type is declared as Object[]. (though it does return an array of the same class)

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb

Aleksei Vasiliev posted:

I'm assuming you're getting an "unchecked cast" warning on the subarray line, since its return type is declared as Object[]. (though it does return an array of the same class)

Yep that's the line. Is my only option to suppress the warning with an annotation?

I did end up going with the guava libraries, lots of neat stuff in there.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

fletcher posted:

Yep that's the line. Is my only option to suppress the warning with an annotation?
Pretty sure Commons Lang 3 made it a generic method, so use that instead of 2. (or use guava or whatever)

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
doubleposting because I have a question:
How do I print Unicode to a Windows console? When running this:
    PrintStream out = System.out;
    out.println("Алексей Федорович Карамазов был только он, "
            + "несмотря даже заметил, так именно и оба");

I get this:
??????? ????????? ????????? ??? ?????? ??, ???????? ???? ???????, ??? ?????? ? ???
This is with UTF-8 as the active code page (chcp 65001), in a font that supports Cyrillic.
Changing the PrintStream declaration to this:
    PrintStream out = new PrintStream(System.out, true, "UTF-8");
Results in printing this:
Алексей Федорович Карамазов был только он, несмотря даже заметил, так именно и оба�смотря даже заметил, так именно и оба так именно и оба�о и оба�баа�
Which is... obviously wrong. It's repeatedly printing the String, in decreasing length and with some random character added in.

This is obviously at least partially a Windows problem but I have no idea what's going on with that last thing. Is all of this Windows issues? Is there any way around it?
(not using code tags since they choke on non-ASCII text)

Tesseraction
Apr 5, 2009

Aleksei Vasiliev posted:

This is obviously at least partially a Windows problem but I have no idea what's going on with that last thing. Is all of this Windows issues? Is there any way around it?
(not using code tags since they choke on non-ASCII text)

I hate to be the one who says "well it works for me" but using your


PrintStream out = new PrintStream(System.out, true, "UTF-8");
out.println("Алексей Федорович Карамазов был только он, "
+ "несмотря даже заметил, так именно и оба");


I got the correct output. What version of Windows / the JDK are you using, have you updated to JDK7?

Imazul
Sep 3, 2006

This was actually a lot more bearable than most of you made it out to be.

Aleksei Vasiliev posted:

doubleposting because I have a question:
How do I print Unicode to a Windows console? When running this:
    PrintStream out = System.out;
    out.println("Алексей Федорович Карамазов был только он, "
            + "несмотря даже заметил, так именно и оба");

I get this:
??????? ????????? ????????? ??? ?????? ??, ???????? ???? ???????, ??? ?????? ? ???
This is with UTF-8 as the active code page (chcp 65001), in a font that supports Cyrillic.
Changing the PrintStream declaration to this:
    PrintStream out = new PrintStream(System.out, true, "UTF-8");
Results in printing this:
Алексей Федорович Карамазов был только он, несмотря даже заметил, так именно и оба�смотря даже заметил, так именно и оба так именно и оба�о и оба�баа�
Which is... obviously wrong. It's repeatedly printing the String, in decreasing length and with some random character added in.

This is obviously at least partially a Windows problem but I have no idea what's going on with that last thing. Is all of this Windows issues? Is there any way around it?
(not using code tags since they choke on non-ASCII text)

try running the JVM with this flag

-Dfile.encoding=UTF8

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
Fully updated American English Windows 7 Pro installed two days ago, JDK7u5, printing to a PowerShell console. Same effect when printing to cmd.exe. Works fine in Eclipse, which makes sense since they have their own implementation of the console, but the weird string repeating thing is what makes me think there is some weird JVM-Windows interplay going on.

The same bug is mentioned here (scroll up one para).

-Dfile.encoding=UTF-8 does not change anything, it prints the same thing.

Tesseraction
Apr 5, 2009

Does this little piss-around solve the issue? It seems like it should help.

Max Facetime
Apr 18, 2009

Aleksei Vasiliev posted:

The same bug is mentioned here (scroll up one para).

This might be a problem in how cmd.exe converts a byte stream into glyphs to be displayed. I think one of those pages mentioned that internally it uses 32 bits per character/codepoint, 16 bits for attributes and 16 bits for a Unicode codepoint.

If I try this
Java code:
    final int LEN = 1;
    for(int i = 0, n = x.length() / LEN; i < n; i++) {
      out.write(x.substring(i * LEN, i * LEN + LEN).getBytes("UTF-8"));
      //out.print(x.substring(i * LEN, i * LEN + LEN));
      out.flush();
    }
    out.println(x.substring(x.length() - x.length() % LEN, x.length()));
this is the result, copied straight from the cmd.exe window, hence the linebreak:

À�ë�å�ê�ñ�å�é� Ô�å�ä�î�ð�î�â�è�÷� Ê�à�ð�à�ì�à�ç�î�â� á�û�ë� ò�î�ë�ü�ê�î� î�í�, í
�å�ñ�ì�î�ò�ð�ÿ� ä�à�æ�å� ç�à�ì�å�ò�è�ë�, ò�à�ê� è�ì�å�í�í�î� è� î�á�à�

However, if I pipe the output to a file instead and open it in Eclipse, it looks fine after changing to UTF-8 encoding, suggesting that java.exe outputs the correct bytes before cmd.exe gets to displaying them.

Edit: I can't copy-paste the Cyrillic characters without mangling them, but they looked correct to me, just alternating with extra unknown character-glyphs.

Edit 2: Using the type command to print the output file in cmd.exe also displays the text correctly.

Max Facetime fucked around with this message at 13:14 on Jul 1, 2012

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
Nope. Exact same issue.
It is useful, though, since changing it around a bit gives me a way of setting up the codepage/font on launch instead of manually.

@I am in: I'm basically going to write this off as Windows being lovely. I get the same result (alternating square characters, looks fine anywhere else, type txt works fine). It seems like I'm really close to getting it to work, except that nothing will get that last step done. Ah well.
(like i'm actually going to stop trying)

Thanks for the help, y'all.

Safe and Secure!
Jun 14, 2008

OFFICIAL SA THREAD RUINER
SPRING 2013
Any good books on Java? I've been using Java off and on, mostly for school projects, for almost seven years now, so I'm extremely comfortable with it, but I want to make sure I'm familiar with all the basic things you would expect someone with a lot of experience to familiar with it. Essentially, I want to get rid of any holes in my knowledge that I'm not aware.

I saw Effective Java, but that seems more like an "advanced" book, rather than a book that will make sure I know basic language stuff like "there are four levels of class access, public, private, protected, and package-protected."

Effective Java is certainly on my list of books to read, but it's not really the book I'm looking for here.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe
I completely disagree with your assessment of Effective Java. It's the book for you to read at this point. It will cover everything you should know to be a better java programmer. It might not cover every API and language construct, but it does cover the most important ones that you will run into frequently.

Max Facetime
Apr 18, 2009

I'll cast my vote for Effective Java as well. This is from the 1st edition:

Effective Java posted:

Item 12: Minimize the accessibility of classes and members
[...]
By making [a top-level class or interface] package-private, you make it part of the package's implementation rather than its exported API, and you can modify it, replace it, or eliminate it in a subsequent release without fear of harming existing clients. If you make it public, you are obligated to support it forever to maintain compatibility.

That sounds way more melodramatic when lifted out of context like that, but the important thing here is that the book explains the purpose of access levels in addition to how many there are and what they do.

Safe and Secure!
Jun 14, 2008

OFFICIAL SA THREAD RUINER
SPRING 2013
Alrighty. I'll just read that instead. Thanks!

Mindisgone
May 18, 2011

Yeah, well you know...
That's just like, your opinion man.
Is anyone familiar with google maps api using javascript? I am specifically trying to use the geocoder api and my code is as follows:
code:
var geocoder;

function codeAddress() {
    var address = document.getElementById("zip").value;
    geocoder.geocode( { 'address': address}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
		  var latlong = results[0].geometry.location;
		  params = "latlng=latlong"
		  request = new ajaxrequest()
		  request.open("POST","cwerksignup.php",true);
          request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
		  request.send(params);
      } else {
        alert("Geocode was not successful for the following reason: " + status);
      }
    });
  }
All I am really trying to achieve here is take the value of 'latlong' (which should be the lat and long of my query) and pass it into a php variable (or right into the html form being posted to the php script). I am not sure of the format of this variable so any info on that would be much appreciated. If I am all hosed up here please let me know.

Doctor w-rw-rw-
Jun 24, 2008

Mindisgone posted:

Is anyone familiar with google maps api using javascript? I am specifically trying to use the geocoder api and my code is as follows:

Javascript is this way.
PHP is that way.

Mindisgone
May 18, 2011

Yeah, well you know...
That's just like, your opinion man.

Doctor w-rw-rw- posted:

Javascript is this way.
PHP is that way.

gently caress me, sorry dude my heads not in the right place right now.

Sereri
Sep 30, 2008

awwwrigami



Off to a good start.

Hughlander
May 11, 2005

I'm trying to understand the proposal for Java 8's Virtual extension methods, but all of the examples and the wording I've seen isn't very clear. I'm coming from a C# background and am used to extension methods, so i'm curious how the two differ.

Specifically all of the examples I've seen have been for cases where you wrote the Interface already. Is it possible to add a virtual extension method to an existing final class? IE: Could I add a function boolean IsPalindrome() to the String class?

In C# this could be done through something like:
code:
namespace CustomExtensions
{
    public static class StringExtension
    {
        public static bool IsPalindrome(this String str)
        {
            // Code to determine if str is indeed a palindrome
        }
    }
}
And then I could have String pal = "racecar"; bool isPalindrome = pal.IsPalindrome();

What would that look like in Java 8 if it's possible?

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
As far as I've seen, Java 8's virtual extension methods are solely for interface providers to use. And the Interface evolution via virtual extension methods paper says:

quote:

In this document, we outline a mechanism for adding new methods to existing interfaces, which we call virtual extension methods.
so it seems working on arbitrary classes/interfaces is not their goal at all.

Max Facetime
Apr 18, 2009

Aleksei Vasiliev posted:

As far as I've seen, Java 8's virtual extension methods are solely for interface providers to use. And the Interface evolution via virtual extension methods paper says:
so it seems working on arbitrary classes/interfaces is not their goal at all.

Thanks, that was an interesting read. My first thought was that it would allow libraries to merge interfaces and their bare-bones abstract implementation classes, leading to shallower inheritance hierarchies, but that seemed more like a footnote in the paper.

Ehh, on the whole it read really rough around the edges, but it's 1 year old already, maybe it has improved.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

I am in posted:

Thanks, that was an interesting read. My first thought was that it would allow libraries to merge interfaces and their bare-bones abstract implementation classes, leading to shallower inheritance hierarchies, but that seemed more like a footnote in the paper.
I think the paper is mostly a proposal from and for the Java... creators? organizers? whatever
so it discusses things that matter most to them, and glosses over stuff like that. If the barebones abstract classes were public, then they can't remove them, since it'd break compatibility. So that's not a particularly important point for them.

Max Facetime
Apr 18, 2009

Aleksei Vasiliev posted:

I think the paper is mostly a proposal from and for the Java... creators? organizers? whatever
so it discusses things that matter most to them, and glosses over stuff like that. If the barebones abstract classes were public, then they can't remove them, since it'd break compatibility. So that's not a particularly important point for them.

I guess, but even then it should allow something like

Java code:
public interface Array<T> {
  int size();
  boolean isEmpty();
}

public abstract class AbstractArray<T> implements Array<T> {
  public boolean isEmpty() { return size() == 0; }
}
to be turned to
Java code:
public interface Array<T> {
  int size();
  boolean isEmpty() default AbstractArray.<T>isEmpty;
}

public abstract class AbstractArray<T> implements Array<T> {
  public static <T> boolean isEmpty(Array<T> array) { return array.size() == 0; }
}
or even this
Java code:
public interface Array<T> {
  int size();
  boolean isEmpty() { return size() == 0; }
}

public abstract class AbstractArray<T> implements Array<T> {
}
or if combined with code generation
Java code:
@HasLegacyAbstractAlias("AbstractArray")
public interface Array<T> {
  int size();
  boolean isEmpty() { return size() == 0; }
}
Anyways, the big problem lurking around the corner stems from a bit weird feature of Java where a single overriding method can end up overriding a second method from an interface that didn't have it when the method was compiled. Example:
Java code:
interface A { void run(); }
interface B { void run(); } // <- added later
class Foo implements A, B {
  public void run() {/* WELL... */}
  //Can't be fixed:
  //public void super.A.run() {run();}
  //public void super.B.run() {}
}
This hasn't been a problem in practice because the lack of multiple implementation inheritance has meant that bigger interfaces where the chance of this happening is higher have almost forced the use of separate subclasses due to the use of abstract default implementation classes.

I remember reading that the invokeinterface bytecode instruction contained almost all the pieces needed for implementing invokedynamic, so maybe that weird little feature has finally paid dividends and it's time to let go of it?

Hidden Under a Hat
May 21, 2003
I'm having an issue with memory leakage related to JPanels. I have data charts (instances of JFreeChart) displayed in JPanels. When the user makes a change to the chart settings, the Chart object is set to null and reinitialized with the new settings, and passed to this method for display in a master JPanel:

Java code:
public void setPanelChart(JPanel newChart){
        masterPanel.removeAll();
        masterPanel.revalidate();
        masterPanel.repaint();
        if(newChart!=null){
            masterPanel.add(newChart,BorderLayout.CENTER);
        }
    }

This problem arises when the user makes too many consecutive changes to the chart settings, I get a OutOfMemory Java Heap Space error. It seems like the old chart objects are not being garbage collected even after they are removed by the RemoveAll() method. Any suggestions to permanently remove those old chart objects?

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.
Have you profiled the app to find out if that's really what's going on?

Hidden Under a Hat
May 21, 2003

trex eaterofcadrs posted:

Have you profiled the app to find out if that's really what's going on?

Yes, the class int[] is ballooning up to over 100 MB, after several invocations of that method. None of the int[] objects that I'm using could possibly cause that much memory to be used, so I imagine it's something that the JFreeChart library is using, which is why I believe chart objects are persisting even though I'm only using one Chart object and reinitializing it when the settings are changed.

Tesseraction
Apr 5, 2009

Hidden Under a Hat posted:

Yes, the class int[] is ballooning up to over 100 MB, after several invocations of that method. None of the int[] objects that I'm using could possibly cause that much memory to be used, so I imagine it's something that the JFreeChart library is using, which is why I believe chart objects are persisting even though I'm only using one Chart object and reinitializing it when the settings are changed.

What are you storing the int[] in? Is that object serialisable? If so, try using reset() to clear any leaking references.

MarshallX
Apr 13, 2004
Not a development question but a thread question (I'm a Java system administrator)

I have 6 LW Processes on an application that are monopolizing CPUs - I converted the LWPIDs to their NID equivalents but thethreads aren't visible in the thread dump. Is there a name for a thread that is doing this? Any way I can determine what they are doing?

prstat:

PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWPID
28695 admin 3446M 3116M cpu5 20 10 1:38:28 11% appservd/18
28695 admin 3446M 3116M cpu2 21 10 1:38:11 11% appservd/19
28695 admin 3446M 3116M run 20 10 1:38:22 11% appservd/16
28695 admin 3446M 3116M cpu3 21 10 1:38:24 11% appservd/20
28695 admin 3446M 3116M cpu0 20 10 1:38:15 11% appservd/15
28695 admin 3446M 3116M cpu1 20 10 1:38:30 11% appservd/17

28695 admin 3446M 3116M sleep 29 10 1:04:39 4.8% appservd/113
28695 admin 3446M 3116M sleep 29 10 0:00:44 0.5% appservd/542
28695 admin 3446M 3116M stop 9 10 0:06:13 0.5% appservd/139
28695 admin 3446M 3116M sleep 29 10 0:07:26 0.5% appservd/79
28695 admin 3446M 3116M sleep 29 10 0:00:48 0.4% appservd/533
28695 admin 3446M 3116M sleep 29 10 0:07:08 0.4% appservd/73
28695 admin 3446M 3116M sleep 29 10 0:06:16 0.4% appservd/145
28695 admin 3446M 3116M sleep 29 10 0:07:23 0.4% appservd/107


Thread Dump:
Sorted by NID

Name Type Prio Thread-ID Native-ID State Address Range
main Task 5 8036448 1 runnable [0x00000000..0xffbfeef0]

should be Threads 0x12->0x20 here which correspond to the above 6 monopolizing threads

VM Thread Task 5 13341816 21 runnable <no address range>
Reference Handler Daemon 10 13345472 22 in Object.wait() [0xf9e3f000..0xf9e3fc28]
Finalizer Daemon 8 13351976 23 in Object.wait() [0xf9daf000..0xf9dafc28]
Signal Dispatcher Daemon 10 13361344 25 waiting on condition [0x00000000..0x00000000]
VM Periodic Task Thread Task 10 8039448 29 waiting on condition <no address range>
Thread-6 Daemon 5 21718256 36 in Object.wait() [0x3112f000..0x3112fc28]



I have no idea why I would see them at the system level but not in a thread dump...is there such thing as defunct threads that aren't a deadlocked thread?

Hidden Under a Hat
May 21, 2003

trex eaterofcadrs posted:

Have you profiled the app to find out if that's really what's going on?

Ok it's definitely the chart object, class instances of the Chart object keep going up even though there should only ever be one Chart object that keeps getting reinitialized. So what are some ways to ensure an object is dereferenced and destroyed?

Max Facetime
Apr 18, 2009

MarshallX posted:

I have no idea why I would see them at the system level but not in a thread dump...is there such thing as defunct threads that aren't a deadlocked thread?

Could those be native threads that have been created by appservd itself rather than the Java VM appservd is running?

Hidden Under a Hat posted:

Ok it's definitely the chart object, class instances of the Chart object keep going up even though there should only ever be one Chart object that keeps getting reinitialized. So what are some ways to ensure an object is dereferenced and destroyed?

Generally no, but you can tap into the running JVM using jconsole and tell it to do a garbage collection to see if you have a leak.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

Hidden Under a Hat posted:

This problem arises when the user makes too many consecutive changes to the chart settings, I get a OutOfMemory Java Heap Space error. It seems like the old chart objects are not being garbage collected even after they are removed by the RemoveAll() method. Any suggestions to permanently remove those old chart objects?
Are you getting any stack trace when it crashes?

1337JiveTurkey
Feb 17, 2005

Hidden Under a Hat posted:

Ok it's definitely the chart object, class instances of the Chart object keep going up even though there should only ever be one Chart object that keeps getting reinitialized. So what are some ways to ensure an object is dereferenced and destroyed?

Look at what listeners you have for components on the old JPanel. I'm pretty sure that's the most likely culprit. If not that, look for any static fields you have in your program, especially collections. Those are garbage collection roots and one of the most common sources of uncollected garbage.

MarshallX
Apr 13, 2004

I am in posted:

Could those be native threads that have been created by appservd itself rather than the Java VM appservd is running?

They should still be part of the thread dump though as the dump is from that PID as well (kill -3 28695)

Typically the application server will have it's own JVM running on another PID.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

Hidden Under a Hat posted:

Ok it's definitely the chart object, class instances of the Chart object keep going up even though there should only ever be one Chart object that keeps getting reinitialized. So what are some ways to ensure an object is dereferenced and destroyed?

Sometimes (but not usually) a static analysis tool like FindBugs can uncover a situation where you're holding a reference that will prevent GC.

Other than that, you have to look at the entire object lifecycle and audit the references to it. Something must be putting it in a collection or some other container that never goes out of scope.

Max Facetime
Apr 18, 2009

MarshallX posted:

They should still be part of the thread dump though as the dump is from that PID as well (kill -3 28695)

Typically the application server will have it's own JVM running on another PID.

Maybe it's a JVM that launched with -Xrs parameter for limited signal handling, so it doesn't respond with a stack trace?

Or could it be a native p_thread that has hung that was created with JNI?

MarshallX
Apr 13, 2004

I am in posted:

Maybe it's a JVM that launched with -Xrs parameter for limited signal handling, so it doesn't respond with a stack trace?

Or could it be a native p_thread that has hung that was created with JNI?

No Xrs but the native p_thread sounds plausible. Just going to send what I can find to Dev and let them dink around with it.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

I'm starting a job next month that will primarily have me be writing Java, so I'm going through Effective Java as per the recommendations in this thread. I've got a question about how method dispatch works when you start calling super(). Consider Item 16 in Effective Java, 2nd Ed.:

code:
public class BrokenEncapsulationTest {

  @Test
  public void testAddCount() {
    InstrumentedHashSet<String> set = new InstrumentedHashSet<String>();

    set.addAll(Arrays.asList("Snap", "Crackle", "Pop"));

    assertEquals(3, set.addCount);
  }

  public static class InstrumentedHashSet<E> extends HashSet<E> {

    public int addCount = 0;

    @Override
    public boolean add(E a) {
      addCount += 1;
      return super.add(a);
    };

    @Override
    public boolean addAll(Collection<? extends E> c) {
      addCount += c.size();
      return super.addAll(c);
    }
  }
}
The assertion fails with 6 instead of 3, I read, because HashSet::addAll() calls HashSet::add() under the hood, so addCount gets incremented more times than it should be.

The progression of calls I was expecting was InstrumentedHashSet::addAll -> HashSet::addAll -> HashSet::add() x 3. That is, I was under the impression that super() kind of acts like a superclass cast, where once you call super() the HashSet object has no notion that it's not at the end of the class hierarchy. What's the right way to think about this?

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.
super.fn() simply calls the method "fn" on its superclass with the current object's data, if the superclass calls an overridden method, it will find the most specific override that matches

E: I should probably be more clear.

The type of the object does not change even when superclass methods are called, so the override will still be "in play" even in super methods.


\/ yeah you did a way better job of explaining than I did

trex eaterofcadrs fucked around with this message at 19:58 on Jul 12, 2012

Adbot
ADBOT LOVES YOU

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Dijkstracula posted:

The assertion fails with 6 instead of 3, I read, because HashSet::addAll() calls HashSet::add() under the hood, so addCount gets incremented more times than it should be.

The progression of calls I was expecting was InstrumentedHashSet::addAll -> HashSet::addAll -> HashSet::add() x 3. That is, I was under the impression that super() kind of acts like a superclass cast, where once you call super() the HashSet object has no notion that it's not at the end of the class hierarchy. What's the right way to think about this?
As you verified with your code the progression was this: InstrumentedHashSet::addAll -> HashSet::addAll -> InstrumentedHashSet::add() x 3

Even though HashSet calls what it thinks is its own add() method, InstrumentedHashSet's method is the one that is called because that's the type of object that you instantiated.

Anytime you overwrite methods in a sub class, all of those methods will be used in any subsequent calls, even if it's from a super class. This is why Bloch says that you have to allow for inheritance explicitly because you don't know what some sub class is going to end up overwriting and loving your poo poo up.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply