Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type variables with limited scope in Java

Tags:

java

generics

I'm wondering if it's possible to introduce type variables within the scope of a method in Java. That is, limiting their scope within the method body.

However, rather than trying to describe the problem in the abstract, let my illustrate with my concrete problem. I have a couple of classes that look a bit like this:

public class Settings {
    public static abstract class Setting<T> {
        public T value;
        public abstract T fallbackvalue();
    }

    private final List<Setting<?>> settings;
}

I now want to write a function, in Settings, for setting the value of all the Settings to their fallback values as provided by the abstract method. My first thought would be to do it like this:

public void reset() {
    for(Setting<?> setting : settings)
        setting.value = setting.fallbackvalue();
}

However, on second thought it is rather obvious why this does not work; the capture of <?> for setting.value is not the same capture as for setting.fallbackvalue(). Ergo, I need some way to unify the captures. It is possible to solve it like this:

private static <T> void reset1(Setting<T> s) {
    s.value = setting.fallbackvalue();
}

public void reset() {
    for(Setting<?> setting : settings)
        reset1(setting);
}

The explicit type variable <T> for reset1 unifies the captures conveniently, but it's obviously the ugliest thing in the world to introduce this function, pollute the namespace, clutter the screen and make the code less readable merely to satisfy the type system.

Is there no way I can do this within the body of reset? What I'd like to do is simply something like this:

public void reset() {
    for(Setting<?> setting : settings) {
        <T> {
            Setting<T> foo = setting;
            foo.value = foo.fallbackvalue();
        }
    }
}

It's not the prettiest thing in the world, but at least to my eyes it is far less strainful than the variant above. Alas, it's not possible; but what is possible, then?

like image 581
Dolda2000 Avatar asked Nov 30 '25 02:11

Dolda2000


2 Answers

There's no way to do what you're asking without changing other aspects of your code. However (to solve your particular issue), you can write a reset method in the inner Setting class:

public void reset() {
    value = fallbackvalue();
}

Then your loop (in the reset method of the Settings class) would simply be:

for (Setting<?> setting : settings)
    setting.reset();
like image 190
arshajii Avatar answered Dec 02 '25 15:12

arshajii


No...

Although wildcard capture does introduce new type variables, they are only available to the compiler; there's no way for programmer to access them directly.

Currently, only class/method can introduce type variables. Therefore the only way to convert an expression type with wildcards to a type without wildcard is to pass the expression through a method (or a constructor with diamond inference new Foo<>(setting) which is essentially the same mechanism)

like image 40
irreputable Avatar answered Dec 02 '25 15:12

irreputable



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!