Rob Spoor

Sheriff
+ Follow
since Oct 27, 2005
Rob likes ...
Eclipse IDE Spring VI Editor Chrome Java Windows
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
131
In last 30 days
1
Total given
60
Likes
Total received
1916
Received in last 30 days
1
Total given
2648
Given in last 30 days
1
Forums and Threads

Recent posts by Rob Spoor

Paul Clapham wrote:Interestingly, it let me use Structured Concurrency classes without checking the "Enable Preview Features" box in the project's properties. Not even a warning. Although it might have been different if I'd tried running the compiled code outside Eclipse, I suppose.


Perhaps because that's not a language feature but an API feature?
4 days ago
Note that functional programming allows us to store the constructor as a field and provide it during construction of instances:
3 weeks ago
What if I did the following?
What would a.f() do, considering that LocalDate doesn't have a no-arg constructor?

But even if you could find a way to declare that a constructor exists (and I actually have devised syntax for this), it's not possible because of type erasure. Generics in Java only exist at compile time. In the compiled byte code it's replaced by the best matching type:
  • With <T> the best matching type is Object
  • With <T extends X> the best matching type is X (for example, <T extends Serializable> leads to Serializable)
  • With <T extends X & Y> the best matching type is X as well. This is why Collections.max uses <T extends Object & Comparable<? super T>> and not <T extends Comparable<? super T>>; the former results in Object which was needed for binary compatibility, the latter results in Comparable
  • With <T super X> and <T super X & Y> the best matching type is Object


  • So your example would compile to this:

    If I would try to access a.a, the compiler turns that into (String) a.a. Because it wouldn't be a String you'd get a ClassCastException.
    3 weeks ago
    Stephan is right.

    A better version would be int mthd(Class<? extends Enum<?>> enum), unless the first version should be <T extends Enum<T>> int mthd(T enum).

    Which one to use depends on what you prefer to read, and whether or not you need that T inside your method.
    1 month ago

    Stephan van Hulst wrote:That would be a really bad idea.

    In essence, that means that I can no longer control whether and how a caller makes an instance of my class, and it also means that I can create instances of classes without providing the bare minimum of information they need for initialization.

    Consider the following example:

    First of all, you're not supposed to instantiate an Integer directly. You're supposed to use a literal or one of the valueOf() factory methods. Secondly, if you DID instantiate an Integer directly, then what would it even mean to instantiate one without a value?

    Remember, according to your proposal, Integer should inherit the parameterless constructor from the Number class.


    This could be circumvented by only automatically creating constructors if no explicit constructors exists. If you create just one constructor manually, no more automatically created constructors. That's already done right now with the no-argument constructor, but this would actually change what the compiler does - a single no-argument constructor might not be added anymore, but several others.

    I don't think Oracle will implement this, and I won't miss it. Within seconds my IDE can create these constructors just as easily (and those seconds are me find the right context menu item).
    1 month ago

    Tim Holloway wrote:Java supports a "universal" file path notation which is essentially that of Unix. There are conversion rules that can map DOS paths to this notation and they necessarily include the drive ID. So "C:\Program Files\java" maps as "/C:/Program Files/java". Resolving in the other direction is ambgious, so expect that "/" will map to the root directory of the currently-logged drive.


    I don't think this is correct. In Windows, it's not allowed to have "/" in file names. Java uses that to translate every "/" into "\", both in the old File class and in NIO/2.
    The file path "/C:/Program Files/java" cannot be used in Windows applications. I've seen it though, but I think that's mostly in URIs. You can use it with File but not with Path.of. You can use "C:/Program Files/java" with both though; that gets translated to "C:\Program Files\java".

    Windows does have a "\" though (which means you can use "/" in Java). It's the root of the current drive, e.g. "C:\" or "D:\".

    Assuming you're not doing something stupid like uploading/creating/altering files within the WAR directory structure. Which will fail horribly on an unexploded WAR.


    Not to mention that with exploded WARs, you'll lose those changes after each deployment.

    One final note. Java is a very bad language to use a "current directory" in. There's only one current directory for a given JVM instance, and since many processes may be running under that JVM, you can not be 100% sure that one of them might change the current directory programmatically at any given time. So as a rule, absolute paths are preferable, the Universal path notation is likewise preferable and ideally that path should include the currently-logged disk when running Windows.


    As far as I know, it's not possible to change the current directory at run time. You can set it when the JVM is started using system property "user.dir", but once the JVM has started, new File(".") and Path.of(".") will always refer to the same file. Unless maybe, very maybe, it's possible with some nasty native code or reflection to change it.
    1 month ago
    The problem is you're mixing Windows and Linux (through wsl).

    In Windows, /Try is equivalent to C:\Try. (It can be on a different drive, that all depends from where Java was started, but you've already shown that the current drive is C:.)
    In Linux, / is just that: /. The matching directory for Windows' C:\ is not / but /mnt/c; you can see that in the console snippets you've shown:

    Anil Philip wrote:


    PS C:\> wsl
    ANIL-PHILIP-LAPTOP:/mnt/c$ sudo mkdir /Try/tea/
    ANIL-PHILIP-LAPTOP:/mnt/c$ sudo mkdir /Try/tea/earlgrey
    ANIL-PHILIP-LAPTOP:/mnt/c$ sudo mkdir /Try/tea/hot.txt



    I can see it did create the files

    ANIL-PHILIP-LAPTOP:/mnt/c$ cd /Try/tea/earlgrey/.././hot.txt
    ANIL-PHILIP-LAPTOP:/Try/tea/hot.txt$ cd ..
    ANIL-PHILIP-LAPTOP:/Try/tea$ ls
    earlgrey  hot.txt


    You see from the prompt that you start in folder /mnt/c, but you create /Try/tea. The second console snippet shows that if you cd into /Try/tea/earlgrey/.././hot.txt the current folder is /Try/tea/hot.txt. That does not match Windows' C:\Try\tea\hot.txt because in wsl that's /mnt/c/Try/tea/hot.txt.
    1 month ago
    That would probably be caused by JEP 396: Strongly Encapsulate JDK Internals by Default and JEP 403: Strongly Encapsulate JDK Internals. Before Java 16, there would be a warning. The first of these JEPS changed the default from warn to fail, but it was still possible to switch back to fail with a JVM flag. The second JEP caused this flag to be ignored; it will be completely removed in some later release.
    1 month ago
    I've become a bit of a fan of @snippet. Before I used a combination of pre and code HTML tags. While that worked, it allowed any code to be included in documentation - even code that didn't even compile. With @snippet I've been able to link to (parts of) actual classes, that I've added to the test source path using Maven. The end result are code snippets that actually compile.
    2 months ago

    Kieu Thoai wrote:So what if I want it to print the word blocked first and then get the result?


    By creating a new CompletableFuture using one of its methods. In this case, since you want the original value, thenApply fits best:
    2 months ago
    PipedReader doesn't override it, and therefore inherits the default behaviour (return false).

    A bit more surprising, the same goes for InputStreamReader. I expected it to delegate to its backing InputStream, but I guess that the "1 byte isn't necessarily 1 char" would have made that tricky.
    2 months ago
    Campbell already moved it for you.

    I noticed that the path that failed had {modulename} in it. I couldn't find any references to it, but I'm guessing that was the issue. Given that the file was called .netbeans_automatic_build makes me think this may have been a glitch in Netbeans.
    2 months ago
    That feature was heavily abused for email viruses. One of the best examples: Anna Kournikova (computer virus). The actual file name was AnnaKournikova.jpg.vbs but Outlook didn't display the actual extension, so it looked like an image file.
    3 months ago
    Be warned that this trySplit is only guaranteed to work if the spliterator is ordered:

    https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Spliterator.html#trySplit() wrote:
    If this spliterator can be partitioned, returns a Spliterator covering elements, that will, upon return from this method, not be covered by this Spliterator.

    If this Spliterator is ORDERED, the returned Spliterator must cover a strict prefix of the elements.


    (On the other hand, if the spliterator isn't ordered, then the stream probably wasn't either, and there's no real definition of "last").

    It also won't work on infinite streams, but then again, no solution would work on infinite streams as these don't have a last element.

    Unless this Spliterator covers an infinite number of elements, repeated calls to trySplit() must eventually return null.

    3 months ago
    On Windows you can still use /. Those get turned into \ for you. Paths.get("/zebra/food.txt") will refer to file <drive>:\zebra\food.txt, where <drive> is the drive of the current directory. Paths.get(".././food.txt") will refer to file <current directory>\..\.\food.txt.

    Esteban, you can check the result of Paths.get("/zebra/food.txt").toAbsolutePath().normalize() and Paths.get(".././food.txt").toAbsolutePath().normalize() to see what files they actually refer to. You can see what the current directory is using Paths.get(".").toAbsolutePath().normalize().
    3 months ago