Stephan van Hulst

Saloon Keeper
+ Follow
since Sep 20, 2010
Merit badge: grant badges
For More
Cologne, Germany
Cows and Likes
Cows
Total received
363
In last 30 days
3
Total given
261
Likes
Total received
3985
Received in last 30 days
33
Total given
728
Given in last 30 days
6
Forums and Threads
Scavenger Hunt
expand Rancher Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Stephan van Hulst

Anil Philip wrote:Below I add Integer and Float to a List<? super Integer>
I should not be able to do that!


You are confusing the static type of the variable with the actual type of the referenced object at runtime.

You didn't add a Double to a List<? super Integer>.

You added a Double to an ArrayList<Object>.

That ArrayList<Object> just happens to be referenced by a variable of type List<? super Integer>, and one of type List<? super Number>. Both are fine.

Maybe it helps if we give a more concrete example:

Obviously, you'd never write actual code like this, but let's just roll with it for now.

The readSensorsInto() method accepts a Collection<? super Number> because it doesn't care whether you pass it a Collection<Number> or a Collection<Object>, as long as it can dump arbitrary numbers into it.

Polymorphism says that you may always assign a reference of some type S to a variable of a supertype T, never the other way around. That means that whatever we assign to the sink parameter, is must be a subtype of Collection<? super Number>. Since we can assign an ArrayList<Number> or an ArrayList<Object>, it necessarily means that those are both subtypes of Collection<? super Number>.

I hope you agree that the following code makes sense:

And that the following code does NOT make sense:

You shouldn't be able to add arbitrary number types into an ArrayList<Integer>.

The rule that allows the sensical use case of passing in an ArrayList<Object> and that prevents the disastrous use case of passing in an ArrayList<Integer> is the rule that says that ArrayList<Object> is a subtype of Collection<? super Number> and that says that ArrayList<Integer> is NOT a subtype of Collection<? super Number>.

Anil Philip wrote:It seems reversed and counterintuitive since Integer is a subtype of Number


Sure, but we're not talking about Integer and Number.

We're talking about List<? super Integer> and List<? super Number>. Different variance, different rules.

Think of a List<? super Integer> as "a list that accepts integers".

Think of a List<? super Number> as "a list that accepts numbers".

A list that accepts numbers is also a list that accepts integers. Therefore, List<? super Number> is a subtype of List<? super Integer>.

Conversely, a list that accepts integers is not a list that accepts numbers, because it can not accept all different kinds of numbers.

Anil Philip wrote:Okay then, how am I able to do this?
Assigning a Float to a list of Integer.


You haven't. You have added a Double to an ArrayList<Object>.

You used the diamond operator to create an ArrayList. The diamond operator inferred that the upper bound of the type parameter is Object.

Then you assigned an ArrayList<Object> to a variable of type List<? super Integer>, which is perfectly legal.
When posting code, please use code tags like [code]this[/code]. This time, I have added them to your posts for you.

Where is configu.xml located inside your project directory? And how do you build and run your application?
1 hour ago

kevin Abel wrote:I have about 25 commands written on paper and typed in a file on EverNote.


That seems like a lot to me. What have you written down?

Question:  What is the difference between main,  the branch with the *,  HEAD and master(obsolete)  ?


There's no conceptual difference between different branches. They're all just labels that point to a commit. You must have at least one branch in your repository. When you initialize a new repository, it used to be the case that the initial branch was named "master" by default. They changed that to "main". So "main" is just the default name of the first branch of your repository. However, it has no special meaning. You can use it the same way as any other branch you create.

HEAD is not a branch. HEAD is a pointer to the currently checked out branch or commit. Checking out means loading the version of the source code into your working directory, so you can make changes to that version of the source code. If you make a new commit, its parent will be the commit that HEAD used to point at before you made the commit.

HEAD is not supposed to point to a commit directly. Instead, you almost always want HEAD to point to a branch label (which in turns points to the checked out commit). The tutorial you're working with could have displayed this by having a HEAD label point to the branch label, but they chose to display this as an asterisk inside the branch label instead. If you see an asterisk, just think "Oh, HEAD is pointing at this branch".

Some commands automatically move the labels around for you, such as when you make a commit or when you merge or rebase branches. But if you want to move the labels around without changing the structure of the commit tree, you can use git branch and git checkout. You move branch labels using git branch. You move HEAD by using git checkout, but remember that git checkout also changes the contents of your working directory to a different version of your source code.


Is there a way to remove the commits at the bottom and then recommit bugFix?


No. A feature of Git is that it almost never removes commits completely. You need to embrace this. It prevents you from accidentally losing data.

The only thing you need to do to fix the situation is move the bugFix label one commit up:
The bugFix branch will now point to commit C2', making commit C4' unreachable (but doesn't delete it completely).

Think of "unreachable" commits as being in your trash can. Until the trash can is emptied, you can still restore those commits by having a branch label point to them.
If you're just rounding off the time part, and you're also just using UTC, then what is the point of returning a ZonedDateTime, and not just a LocalDate?
11 hours ago
A type can not be a subset of another type because types are not sets.

You can assign a String to a variable of type Object because String is a subtype of Object.

You can assign a List<? extends Integer> to a variable of type List<? extends Number> because List<? extends Integer> is a subtype of List<? extends Number>.

If List<? super Integer> were a subtype of List<? super Number>, you would be able to assign a List<? super Integer> to a variable of type List<? super Number>. You can't, because it doesn't make sense and would lead to broken code:

If the second statement were allowed, we would be able to add a Float to a List<Integer>.
Your bean definition file is not located on the path you indicated when you created your application context.

Please show us how you initialize your application, and where your configuration file is located in your project directory.

Is there a reason you're not using Spring Boot to initialize your application?
21 hours ago

kevin Abel wrote:I think that I'm missing a middle piece of knowledge.   I know the basics of git and very little of branching.  These examples seem to be for more advanced branching.  Is that correct?


Branching IS the basics of Git. Without branching, Git is nothing more than a simple backup tool. The examples you've worked through currently are quite basic.

To use Git effectively, at the very least you need to be familiar with creating branches, checking out branches, and rebasing (or preferably merging) branches.

The situation where you have to move around branch pointers using the git branch command doesn't really happen that much in real life. But it's still useful to know how to do it, if only so you can get a feeling for what a branch pointer is in the first place.


I'm enjoying going through the teaching screens, guessing at the answers and then seeing how the answers work.


I think the problem is that you're guessing. If you feel you need to guess, then you haven't internalized the previous lessons.


I'll go back to W3schools for git because there has to be some base knowledge that I don't have.


The tutorial is pretty much self-contained. You don't need to read anything else to complete the tutorial, as long as you remember the commands you've learned from earlier lessons.

You seem to have problems with the git branch command. It won't do to try and guess the correct way to call the command. If you do that in real life you will make a mess of your branches.

Level 3 of the second series ("Ramping up"; "Relative Refs #2") explains how you use the git branch command to move a branch pointer to a different location. Review that lesson before you try the level you're stuck on.

Don't worry, in real life you don't have to remember how to call every single git command. But you need to know roughly what you can do with a certain command, and then you can just look up how to call the command in the git handbook.


It was a bad time to get hit with covid.    I run into a new thing to learn and my mind only wanted rest.  I slept for about 18 hours a day back and when I woke up I felt great but tired.


I'm very sorry to hear that. Hopefully you'll be back to your old self soon. Covid seems to be going strong again lately.

Anil Philip wrote:If this is not allowed by the language then why does it compile?


Nobody said it's not allowed. It's just not possible to call the implementation of a grandparent class A if the implementation has been overriden by a parent class B. You can use the method name given by the grandparent just fine, but it will execute the implementation given by the object's actual type at runtime, which in this case is C.

Calling the method m1() on an object of type C will always call C.m1(). It doesn't matter that the reference that points to the object is of type A, the referenced object is still an object of type C. Casting the reference to a different type also doesn't make a difference. The object that the reference points to remains of type C.

This is the entire point of polymorphism: the behavior of an object is always determined by the actual type of the object at runtime, no matter the type of the reference that point to it.

Furthermore, why is it in an infinite loop?


Now that you know that calling m1() on your object always calls the implementation given by class C, it is easy to see why the code appears to loop: C.m1() calls C.m1() in its method body, which in turn calls C.m1(), which calls C.m1(), which...

wonder if the compiler is not clever enough to catch the flow of execution.


Clever enough to do what? Detect an infinite recursive call? Why would it do that?

There are legitimate reasons to make a recursive call, and it's not trivial to detect the recursion won't be infinite. In fact, if you can solve that problem, you've solved the Halting Problem and everything we know about computer science will be different forever.

If you assign a C instance to an A reference and cast it, then one can access only the member variable of A but not execute its methods?


You can access any visible member of A. But for instance methods, calling the method means the implementation given by C will be executed. This is polymorphism.
1 day ago
Please show us:

  • AbstractCustomerApproveTypeAction
  • struts-config.xml

  • 2 days ago
    No, what I mean is, why would the cancel tag specifically call a method named "unspecified"? Why not "other" or "cancel" or any other arbitrary name?

    Where did you get the method name "unspecified" from?
    2 days ago
    What makes you think the unspecified() method should be called?
    3 days ago