News for hackers. Stuff that matters.
Re:Java record pattern matching in JDK 19 by swaranga on Saturday May 14, 2022 @12:47PM (#31379783)
There are some edge cases because of which this had to be done, I think. For example calling static methods via the instance variables, the actual method called would be the static type of the variable at compile time and not the actual type at runtime:

    public static void main(String[] args) {
        Parent instance = new Child();

        if (instance instanceof Child p) {
            instance.print(); // prints Parent
            p.print(); // prints Child
        }
    }

    static class Parent {
        static void print() {
            System.out.println("Parent");
        }
    }

    static class Child extends Parent {
        static void print() {
            System.out.println("Child");
        }
    }
Hence, with flow typing, existing code could break in subtle ways.
Re:Java record pattern matching in JDK 19 by smarks on Saturday May 14, 2022 @07:37PM (#31383787)
Several folks have pointed out the poor style in calling static methods using an instance. I think you have a good point, but not a good example. Perhaps a better example is with overload resolution. Consider this Kotlin code:

    fun foo(i: Int) = ...

    fun foo(n: Number) = ...

    fun main() {
        val n: Number = 12;
        foo(n); // calls foo(Number)
        if (n is Int) {
            foo(n); // calls foo(Int)
        }
    }
It's as if smart casting causes the static type of `n` to change in different parts of the main function. As such it also seems to affect overload resolution. Maybe this is exactly what you want. On the other hand it seems like it could lead to some very subtle errors. I'm not a Kotlin programmer, so Kotlin experts please feel free to correct me on details.
Re:Java record pattern matching in JDK 19 by yarg on Saturday May 14, 2022 @06:23PM (#31383240)
Does java provide warnings against calling static methods on Objects?
Re:Java record pattern matching in JDK 19 by smarks on Saturday May 14, 2022 @06:34PM (#31383345)
Yes, if javac is given the `-Xlint:static` option.
Re:Java record pattern matching in JDK 19 by hilbertseries on Saturday May 14, 2022 @06:50PM (#31383483)
If you’re writing code calling static methods on instances of classes, you deserve to have that code broken.
Re:Java record pattern matching in JDK 19 by quantified on Saturday May 14, 2022 @08:37PM (#31384160)
Probably didn’t get written that way but arrived there when that class was refactored somehow.
Re:Java record pattern matching in JDK 19 by recursive on Saturday May 14, 2022 @07:07PM (#31383583)
I've always wondered why that's even allowed.
Re:Java record pattern matching in JDK 19 by _Nat_ on Saturday May 14, 2022 @09:49PM (#31384542)
It's actually the default in C#.

This is, in C#, all methods are called according to an object's apparent-type, not its actual-type, by default. To get the Java-behavior, a C#-method would need to be declared `virtual` (or `abstract`), and then more-derived methods would need to choose to `override` them (rather than hide them, often via `new`).

Part of the advantage might be performance. This is, methods that go with the apparent-type don't need to do a virtual-lookup-table resolution, which can save some work in method-calls.

Another advantage is that it can help provide more flexibility in class-hierarchies, since more-derived classes can "hide" less-derived classes' methods without overriding them. It's probably not something that folks really need to do too often, but it's nice to have an easy solution when such a case occurs.

Re:Java record pattern matching in JDK 19 by recursive on Sunday May 15, 2022 @01:42AM (#31385511)
You're talking about virtual vs non-virtual. static is a whole separate thing. static calls are always resolved at build time. You don't even need an instance at all. And probably shouldn't use one.
Re:Java record pattern matching in JDK 19 by _Nat_ on Sunday May 15, 2022 @03:19AM (#31385859)
Right -- it's an issue of virtual vs. non-virtual, not static vs. non-static.

For example, [this comment](https://news.ycombinator.com/item?id=31379783 ) provided code showing the issue in this branch of the thread using `static` in Java. Here's the same thing in C# without using `static` (except for `Program.Main()`):

    public class Program
    {
        public static void Main()
        {
            A a = new B();
            
            if (a is B b)
            {
                a.Print();  // Prints "A".
                b.Print();  // Prints "B".
            }
        }
    }
    
    public class A { public void Print() { System.Console.WriteLine("A"); } }
    public class B:A { public new void Print() { System.Console.WriteLine("B"); } }
`static` can work too because it implies non-virtual, but it's not necessary.

Generally speaking, virtual-methods resolve with dependence on the object they're called on since they consult a [virtual-method table](https://en.wikipedia.org/wiki/Virtual_method_table ). Non-virtual methods can resolve without considering the object they're called on (whether static or not) because they call the method that belongs to the apparent-type.

Re:Java record pattern matching in JDK 19 by recursive on Sunday May 15, 2022 @01:48PM (#31389388)
> it's an issue of virtual vs. non-virtual, not static vs. non-static.

That's what you started talking about, but that's not what I'm talking about.

> "calling static methods on instances of classes"

That's from an ancestor, somewhere upthread. Here it is as a c# expression.

    "abc".Format("size: {0}", 7)
Sensibly, c# doesn't allow this, but some languages do. I don't recall which, but I've definitely seen this.

Maybe I'm not understanding a word or something, but the description of the problem is definitely about "static".

Re:Java record pattern matching in JDK 19 by _Nat_ on Wednesday May 18, 2022 @12:32PM (#31424764)
In C#, basically all methods are `static` by-default. Just, if a programmer doesn't explicitly mark a method as `static`, then the compiler implicitly inserts an extra argument into the call-signature for `this`.

For example:

    public class A
    {
        //  If a programmer writes this:
        public void DoSomething(int x) { /* ... */ }
    
        //  ...then C# sees this:
        public static void DoSomething(A this, int x)
        {
            if (this == null) { throw new NullArgumentException(); }
            /* ... */
        }
    }
So if a programmer then writes `a.DoSomething(7);`, C# basically automatically converts that into `A.DoSomething(a, 7);` for them. It's basically syntactic-sugar.

C# even lets programmers write methods that can be called on an instance OR as `static`: [extension methods](https://docs.microsoft.com/en-us/dotnet/csharp/programming-g... ).

Then there's a difference between C# and Java: in C#, non-static methods can be `virtual` if marked as such, whereas in Java, all non-static methods are automatically `virtual`.

---

Anyway, my point about the perspective from [this comment](https://news.ycombinator.com/item?id=31383483 ),

> If you’re writing code calling static methods on instances of classes, you deserve to have that code broken.

, was that that's basically what C# does by-default, ignoring syntactic-sugar.

Because, in C#, methods aren't `virtual` by-default, so when C#-programmers call a default method on an instance, they're calling it non-virtually, much like a Java-`static` method -- it may look a little different in C# due to the syntactic-sugar, but it's basically the same thing.

To demonstrate that same-ness, I took the Java code that used `static` from [this comment](https://news.ycombinator.com/item?id=31379783 ), then showed the same without `static` in C# in [this comment](https://news.ycombinator.com/item?id=31385859 ).

Of course, I don't mean that they look exactly the same, due to the syntactic-sugar. Just that they're conceptually the same in terms of logical-structuring and behaviorally the same in terms of what they actually do (e.g., how they printed the same responses in those examples).

Re:Java record pattern matching in JDK 19 by pjmlp on Sunday May 15, 2022 @04:39AM (#31386194)
Influence from OOP languages that preceded Java.
Re:Java record pattern matching in JDK 19 by SemanticStrengh on Saturday May 14, 2022 @01:22PM (#31380200)
How does Kotlin solve those use cases?

> instance.print(); // prints Parent

why? the parent print should be shadowed/overidden by the child bruh

Re:Java record pattern matching in JDK 19 by spullara on Saturday May 14, 2022 @01:38PM (#31380361)
statics don't override
Re:Java record pattern matching in JDK 19 by SemanticStrengh on Saturday May 14, 2022 @01:57PM (#31380552)
oops my bad