Static Method in a Generic Class

Static method in a generic class?

You can't use a class's generic type parameters in static methods or static fields. The class's type parameters are only in scope for instance methods and instance fields. For static fields and static methods, they are shared among all instances of the class, even instances of different type parameters, so obviously they cannot depend on a particular type parameter.

It doesn't seem like your problem should require using the class's type parameter. If you describe what you are trying to do in more detail, maybe we can help you find a better way to do it.

How to make a Java Generic method static?

the only thing you can do is to change your signature to

public static <E> E[] appendToArray(E[] array, E item)

Important details:

Generic expressions preceding the return value always introduce (declare) a new generic type variable.

Additionally, type variables between types (ArrayUtils) and static methods (appendToArray) never interfere with each other.

So, what does this mean:
In my answer <E> would hide the E from ArrayUtils<E> if the method wouldn't be static. AND <E> has nothing to do with the E from ArrayUtils<E>.

To reflect this fact better, a more correct answer would be:

public static <I> I[] appendToArray(I[] array, I item)

How do I call a static method on a generic class without specifying a type?

You can make a separate class with the same name but no type parameters.

Note that the type parameters are part of the identity of the class. If you're trying to clear all fields in all type-parameterized versions of your class, that isn't directly possible.

Java Generics - How to write static methods with type arguments?

If you want to put type parameters on a method, you just stick them before the return type (which you probably didn't want to be void):

public static <T extends Comparable<T>> T findMax(T a, T b) {
...
}

In most cases, you can skip the type parameters at the call site, and they'll be inferred for you:

Integer max = WhateverClass.findMax(integerA, integerB);

Why do I have to use T on static method call on a generic class

Because you haven't created a class called GenericClass, you've created an open generic class called GenericClass<T>.

There is nothing to stop you from also creating a class GenericClass in the same namespace, and nothing to stop you from creating also a class called GenericClass<T1,T2>. All of these could exist in the same namespace and have no explicit or implicit relationship between them, unless you declare one.

So, if you want to invoke a static method on "the GenericClass class that is generic in one type parameter", you've got to say that somehow, and you've found how to do it - by supplying a type parameter.

One could argue that, if the static method doesn't use the type parameter, it's redundant - so why can you not call it just by using the still-open type parameter? Well, firstly because that would have to be new syntax to allow that to happen1. And second, what happens if your method accesses any static fields? With generic types, each unique type used as the type parameter causes a new set of static fields to exist.


why isnt the syntax for static methods genericClass<T>.StaticMethod(); for example as ...

The above was added after my initial answer and I'd hoped this was already addressed in footnote 1 below. But in case it's not clear, this simple syntax won't work. You need to invent some new syntax because you might have:

class Abc<T> {
void DoSomething(){
GenericClass<T>.StaticMethod();
}
}

or

namespace X {
class T {
}
class Abc {
void DoSomething(){
GenericClass<T>.StaticMethod();
}
}
}

In both of the above examples T is already defined by the outer scope. So you need some other way of saying "I don't want to supply a type for the first type parameter of this generic".


1E.g. being able to say GenericClass<T>.Showcase. Any new syntax to allow it couldn't be so straightforward. Because a) there may be a generic type parameter T in scope in the calling context, or b) the name of the generic type parameter may clash with some other type name that is in scope in the calling context.

Calling a static method using generic type

No you cannot do it if A is a generic type. (Bozho answered to fast :) and probably thought A was concrete type.

What will work is the following.

abstract class Agent extends Blah<ConcreteA>{
void callAgent();
Agent() {
ConcreteA.add();
}
}

but it's probably not what you want to do.

After reading your comments it sounds like what you really want to do is:

abstract class Agent<A extends SomeClassThatSupportsAdd> {

void callAgent();
protected abstract A createNew();

Agent() {
A a = createNew();
A.add();
}
}

Your subclasses will have to override createNew().

If you still do not like that you can take a look at AspectJ which will allow you to do some constructor magic (see how spring does @Configurable) but that gets far trickier and complicates things.

Another option is Scala. Java does not do inheritance on static methods so you can't get parameterized modules (groups of functions in some languages this is called a functor ... ocaml). However Scala supports a singleton "object" that does allow for parametric functional polymorphic inheritance.

Typescript generic class type with static methods

ClassType should be declared as

type ClassType = typeof Dog | typeof Cat;

And the getAnimalSound should be transformed into:

const getAnimalSound = (type: ClassType): string => type.getSound();

Now, if we call

console.log(getAnimalSound(Dog));
console.log(getAnimalSound(Cat));

their sounds can be heard.

The issue in the original approach is that the static methods belong to the class object and they cannot be invoked on an instance, so we need to access the type reference.

In fact, the static "inheritance" in the original approach does not make sense, because these methods are invoked as Animal.getSound(), Dog.getSound() etc.



Related Topics



Leave a reply



Submit