Generic-Funktion nur bei bestimmten Typen erlauben

CSHW89

Bekanntes Mitglied
Hi Leute,

ich hab gerade mal ein kleines nicht altägliches Generic-Problem. Vielleicht hat ja jemand eine Idee. Ich möchte eine Funktion in einer Generic-Klasse nur Objekten zur Verfügung stellen, die eine bestimmte Eigenschaft haben. Hier soll die addInt-Funktion nur aufrufbar sein, wenn der Parametertyp T von List<Integer> erbt.
Java:
import java.util.*;

public class TestGeneric<T> {
    
    private Map<String, T> map;
    
    public void addInt(String name, Integer value) {
        T arr = map.get(name);
        
        if (arr == null) {
            ArrayList<Integer> arr2 = new ArrayList<>();
            arr2.add(value);
            map.put(name, (T) arr2);
        }
        else {
            ((ArrayList<Integer>) z).add(value);
        }
    }
    
    public <F extends T & List<Integer>> void addInt2(String name, Integer value) {
        F arr = map.get(name);
        
        if (arr == null) {
            arr = new ArrayList<>();
            arr.add(value);
            map.put(name, arr);
        }
        else {
            z.add(value);
        }
    }
    
    public <F extends List<Integer> & T> void addInt3(String name, Integer value) {
        F arr = map.get(name);
        
        if (arr == null) {
            arr = new ArrayList<>();
            arr.add(value);
            map.put(name, arr);
        }
        else {
            z.add(value);
        }
    }
    
    public static void main() {
        new TestGeneric<List<Integer>>().addInt("h", 2);
        new TestGeneric<Object>().addInt("h", 2);  // soll Compiler-Error erzeugen
    }
    
}
Die Funktion addInt macht dies, allerdings nicht typensicher. In der main würde es dann zu einem Laufzeitfehler führen. Bei den anderen beiden Varianten hab ichs mit nem neuen Typparameter versucht. Beide lassen sich aber leider nicht compilieren.

Das hier ist übrigens nur ein Beispiel. Mein konkreter Fall sieht etwas anders aus. Es ist jetzt auch nicht mega wichtig, da die erste Variante ja funktioniert. Ich fände es nur interessant, ob es dafür ne Lösung gibt.

lg Kevin
 
Zuletzt bearbeitet:

Ruzmanz

Top Contributor
Ich würde spontan sagen, dass das nicht geht. Zumindest nicht ohne eigene Compiler-Warnung zu schreiben. Vielleicht habe ich die Frage falsch verstanden, da du sehr viel unnötigen Quellcode gepostet hast ...

Java:
import java.util.List;

public class TestGeneric<T> {

	public void addInt(String name, Integer value) {}

	public static void main() {
		new TestGeneric<List<Integer>>().addInt("h", 2);
		new TestGeneric<Object>().addInt("h", 2); // soll Compiler-Error erzeugen
	}
}

Mit Vererbung:

Java:
public class TestGeneric<T> {}

public class TestGenericInt<T extends List<Integer>> extends TestGeneric<T> {

	public void addInt(String name, Integer value) {}

	public static void main() {
		new TestGenericInt<List<Integer>>().addInt("h", 2);
		new TestGenericInt<Object>().addInt("h", 2); // soll Compiler-Error erzeugen
		new TestGeneric<List<Integer>>().addInt("h", 2); // soll Compiler-Error erzeugen
	}
}
 

Network

Top Contributor
Naja du könntest das hier verwenden um den Objekttypen herauszufiltern
Java:
public void addInt(String name, Integer value) {
        if( T instanceof List<Integer> ) {
                T arr = map.get(name);
               
                if (arr == null) {
                    ArrayList<Integer> arr2 = new ArrayList<>();
                    arr2.add(value);
                    map.put(name, (T) arr2);
                }
                else {
                    ((ArrayList<Integer>) z).add(value);
                }
        }
}
 

Natac

Bekanntes Mitglied
Naja du könntest das hier verwenden um den Objekttypen herauszufiltern
Java:
if( T instanceof List<Integer>)
So ein Konstrukt funktioniert in Java NICHT! Die Generics sind nur zur Compile-Zeit bekannt. Der Kompilier ersetzt alle Generics durch entsprechende Casts, so dass du im Bytecode keine Generics mehr finden wirst.

Dementsprechend kann man diese auch nicht per instanceof prüfen. Bitte schreibe doch das nächste mal dazu, dass dies eine Vermutung von dir ist. Den Code so hinzuschreiben und damit zu propagieren, dass er funktionieren würde, halte ich für gefährlich.

EDIT: Zumal du den generischen Typparameter T sowieso nicht prüfen kannst (dieser ist noch nicht einmal eine Variable). :autsch: Wenn du dich mit Generics nicht auskennst (was dein Post nahelegt), dann halte dich bei solchen Themen doch bitte einfach zurück oder teste deinen Code, bevor du ihn postest. :rtfm:
 
Zuletzt bearbeitet:

CSHW89

Bekanntes Mitglied
@Ruzmanz: Ja stimmt, Vererbung wäre noch ne Möglichkeit. Allerdings wäre es in meinem Fall wieder etwas zu viel Overhead (aber danke für die Idee). Ich denke, ich bleibe bei meiner ersten typunsicheren Variante. Ich benutze es ja z.Z. nur für mich. Mich hatte es halt interessiert, ob es in Java möglich ist, einzelne Funktionen aus der Generic-Klasse sozusagen herauszufiltern bei bestimmten Generictypen.

Ich frage mich aber schon, warum der Multibound bei Funktionen nicht funktioniert:
Code:
<F extends T & List<Integer>>

@Natac: :) ja wie du schon sagst, das kann aus zwei Gründen nicht funktionieren. T ist kein Objekt, und instanceof funktioniert nicht mit Generics.

lg Kevin
 

Network

Top Contributor
So ein Konstrukt funktioniert in Java NICHT! Die Generics sind nur zur Compile-Zeit bekannt. Der Kompilier ersetzt alle Generics durch entsprechende Casts, so dass du im Bytecode keine Generics mehr finden wirst.

Dann hast du denn Sinn von Generics nicht verstanden. Bei Generics ist es so, dass das Objekt dem Compiler NICHT bekannt ist, sondern erst zur Laufzeit!
Das ist der gesammte Sinn dahinter.
Und natürlich findet man keine Generics mehr später im Bytecode, es handelt sich hierbei ja auch nicht um Klassen/Objekte sondern um "Regeln" um den Compiler zu sagen, was man denn dort erwartet, damit er auf Fehler gegenprüfen kann.

Dementsprechend kann man diese auch nicht per instanceof prüfen. Bitte schreibe doch das nächste mal dazu, dass dies eine Vermutung von dir ist. Den Code so hinzuschreiben und damit zu propagieren, dass er funktionieren würde, halte ich für gefährlich.

Selbstverständlich kann man das per instanceof prüfen. Wenn dem Programm später nicht bekannt wäre um was für Objekte es sich dabei handelt, wie kann es dann die entsprechenden Methoden aufrufen?
Wie funktioniert dann das hier zur Laufzeit?:
(theoretischer Code) "[<T extends List<Integer>].add( 1 )"
Nach deiner Theorie dürfte die JRE zur Laufzeit garnicht wissen, dass es sich um ein Objekt das von List<Integer> erbt, handelt und könnte entsprechend nicht die Methode ".add(1)" aufrufen.

Zur Laufzeit sind die Informationen also da und man kann entsprechend auch Gegenprüfen per instanceof!
Ich finde es witzig, dass du mich dafür anmachst ich würde meinen Code nicht testen und das würde so nicht funktionieren, obwohl du ihn nicht einmal selbst gegengetestet hast!

Hier ein kleines KSKB das instanceof in Verbindung mit Generics zeigt
Java:
import java.util.ArrayList;

import javax.swing.JFrame;

public class Test<T> {
	public static void main(String[] args) {
		new Test<String>("String", "Hallo");
		new Test<Integer>("Integer", 1);
		new Test<JFrame>("JFrame", new JFrame());
		new Test<ArrayList<Integer>>("ArrayList<Integer>", new ArrayList<Integer>());
		new Test<ArrayList<String>>("ArrayList<String>", new ArrayList<String>());
	}
	
	public Test(String name, T test) {
		System.out.println("Object: " + name + " is " + ((test instanceof ArrayList<?>) ? "DEFINITLY" : "NOT") + " an instance of \"ArrayList<?>\"");
	}
}

Direkt auf List<Integer> kann man aber nicht testen, das war mir nicht bewusst gewesen. In C# funktionieren Generics in diesem Zusammenhang anderst, dort werden die Informationen direkt hinterlegt.
Das macht meinen Vorschlag in der Theorie aber nicht weniger Wert, in diesem Zusammenhang funktioniert er aber nicht, da List selbst noch auf Integer geprüft werden müsste.

EDIT: Zumal du den generischen Typparameter T sowieso nicht prüfen kannst (dieser ist noch nicht einmal eine Variable). :autsch:

In der Tat habe ich mich dort vertan bzw zu schnell gedacht. Aber die Idee sollte rübergekommen sein, ob ich jetzt T oder t schreibe. Vielen Dank für die Verbesserung.

Wenn du dich mit Generics nicht auskennst (was dein Post nahelegt), dann halte dich bei solchen Themen doch bitte einfach zurück oder teste deinen Code, bevor du ihn postest. :rtfm:

Jetzt haste dir aber ganz schön selbst ins Bein geschossen, kann das sein? Das nenn ich Karma - ich möchte dich daher bitte in Zukunft nicht mehr in Fragen über Generics sehen!

Aber frech ist es trotzdem allemal, insbesondere da ich wahrscheinlich mehr Jahre Programmiererfahrung habe, als du Jahre auf dem Buckel hast.
Man kann nunmal nicht immer richtig liegen. Ich opfere hier zumindest meine kostbare Freizeit unentgeltlich und beantworte Fragen auf dem Weg zur Arbeit um 5e morgens und nach 12Std wieder auf dem Weg zurück auf meinem Handy. Da habe ich keinen Compiler, ich bin aber auch keine Hausuafgabenmaschine die fertigen Code ausspuckt, sondern liefere Vorschläge. Ob und wie diese Vorschläge weiter verarbeitet werden kann ich nicht beeinflussen. Jeder Mensch sollte Intelligenz an den Tag legen können und wer sich nicht die Mühe macht, hat es auch nicht verdient und sollte sich vielleicht mit etwas anderem beschäftigen.


@TO
Da lag ich wohl tatsächlich leicht daneben. In deinem Anwendungsfall funktioniert das in der Praxis tatsächlich nicht (aber nicht aus den genannten Gründen).
An deiner Stelle würde ich mir aber eher Gedanken machen über die Programmarchitektur. Wenn bei mir einer mit so einem Code ankommen würde, dann gäbs n Satz heiße Ohre. ;) :)
 
Zuletzt bearbeitet:

Natac

Bekanntes Mitglied
Okay... halten wir als erstes fest, das mein Post vielleicht etwas zu aggressiv verfasst wurde. Sorry dafür. Wollte in keiner Weise deine Programmiererfahrung oder den Einsatz deiner Freizeit in Frage stellen.

Ich hatte mich auf folgende von dir geposteten Codeschnipsel bezogen:
Java:
if( T instanceof List<Integer> ) {
  T arr = map.get(name);
Für mich siehst du hier T als Typ an (
Code:
T arr =
). Daher mein Hinweis, dass man den generischen Typ gar nicht prüfen kann. Das du eigentlich
Code:
t
(als Variable) meinst, ist aus dem Code leider nicht ersichtlich.

Und das man gar nicht auf
Code:
List<Integer>
prüfen kann, hast du ja schon selbst eingesehen.

Mehr wollte ich mit meinem Post gar nicht sagen. Die Kombination deines "Vertippens"(t/T) und das Detail, dass man eben nicht gegen List<Integer> prüfen kann, haben eben einen falschen Eindruck von dir bei mir hinterlassen. :bahnhof:
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
O Werte einer Generic LinkedList zusammenrechenen Allgemeine Java-Themen 14
Rakshan Generic reading of XML document from the root tag into an Collection Allgemeine Java-Themen 0
B In Java Methode mit generic input und output basteln? Allgemeine Java-Themen 4
N Generic Type einer Generischen Klasse während der Laufzeit bekommen Allgemeine Java-Themen 2
S Problem mit Generic bei unmodifiableCollection Allgemeine Java-Themen 4
Neumi5694 Methoden Generic: Rückgabetyp als Class-Parameter übergeben Allgemeine Java-Themen 3
Neumi5694 Datentypen Generic mit parameterlosem Konstructor Allgemeine Java-Themen 4
C Generic collections und static typing Allgemeine Java-Themen 4
K Generic class und Reflection Allgemeine Java-Themen 2
K Saubere Verwendung von Generic Types Allgemeine Java-Themen 7
T Generic Allgemeine Java-Themen 1
M Cannot create a generic array of T Allgemeine Java-Themen 5
N Generic extends Generic Allgemeine Java-Themen 5
TheWhiteShadow Generic Bug? Allgemeine Java-Themen 19
P Generic zur Laufzeit Allgemeine Java-Themen 4
X Generic muss zwei Klassen/Interfaces erfüllen Allgemeine Java-Themen 5
S Reflection und Generic Allgemeine Java-Themen 9
G Klasse eines Generic Allgemeine Java-Themen 6
J Generic von einer ArrayList/HashMap bekommen Allgemeine Java-Themen 7
G Generic merhfach Angabe Allgemeine Java-Themen 8
Dragonfire Generic Typ zur Laufzeit Allgemeine Java-Themen 9
N Casten durch generic vermeiden ?? Allgemeine Java-Themen 10
N generic reflection Allgemeine Java-Themen 5
thE_29 Generic Methoden die sich aufrufen wollen nicht immer Allgemeine Java-Themen 12
A Generic-Problem. was meint ihr dazu? Allgemeine Java-Themen 4
G unbekanntes Generic Allgemeine Java-Themen 12
K Bound mismatch: The generic method sort(List<T>) of ty Allgemeine Java-Themen 4
V ArrayList ist nicht generic!?? Oder bin ich blöd? Allgemeine Java-Themen 2
G [quote]the type HashMap is not generic; it cannot be paramet Allgemeine Java-Themen 4
C Generic Type ermitteln Allgemeine Java-Themen 3
H References to generic type Test.A<typ> should be param Allgemeine Java-Themen 5
byte Generic Type einer List zur Laufzeit rausfinden? Allgemeine Java-Themen 4
Alex_99 Programm stürzt beim Aufruf der Funktion ab? Text ausgeben Allgemeine Java-Themen 45
_user_q Was brauche ich, um eine eigene "Search for updates"-Funktion einzubauen? Allgemeine Java-Themen 1
Tobero Meine Funktion für das beinhalten eines Punktes in einem Kreis funktioniert nicht Allgemeine Java-Themen 5
S Validation Annotation Funktionsparameter vs Funktion vs Attribut Allgemeine Java-Themen 0
R Variablen String mit split-Funktion aufteilen Allgemeine Java-Themen 7
A Serialize - Add Funktion Allgemeine Java-Themen 1
B Discord Bot - Funktion wird nicht aufgerufen Allgemeine Java-Themen 1
A Variablen Funktion übergibt den Wert nicht Allgemeine Java-Themen 13
J Überschriebene Funktion soll nicht die super Funktion aufrufen Allgemeine Java-Themen 4
Aruetiise Funktion(y = mx+n) in String speichern und berechnen Allgemeine Java-Themen 9
B Hilfe!! spiel um Funktion des Selektierens erweitern (mit ASCII-Tabelle) Allgemeine Java-Themen 3
MiMa ArrayList Rückgabewerte aus einer Funktion Allgemeine Java-Themen 15
B Gibt es eine Funktion die den Datentyp einer Variablen ermittelt? Allgemeine Java-Themen 8
A Plot funktion applet Allgemeine Java-Themen 4
S Methoden "Unschöne" Break-Anweisung aus verschachtelter Funktion entfernen Allgemeine Java-Themen 11
R Rückgabe eines Arrays durch Funktion Allgemeine Java-Themen 9
T Best Practice MD5 Funktion Allgemeine Java-Themen 9
perlenfischer1984 Testng : Funktion mit mehreren Parametern testen Allgemeine Java-Themen 5
L Stack overflow bei einer endrekursiven Funktion (Anwendung: Spezialform des Package Merge) Allgemeine Java-Themen 4
C Klassen Problem mit Funktion einer Generischen Klasse die ein Interface implementiert Allgemeine Java-Themen 0
O JNA Zugriff auf Funktion aus DLL Allgemeine Java-Themen 0
Lord.Djerun (Taschenrechner) jButtons mit gleicher Funktion zusammenfassen Allgemeine Java-Themen 6
I Javafx Open/Read und Tree Funktion Allgemeine Java-Themen 14
F Classpath als Argument in Funktion übergeben Allgemeine Java-Themen 3
H SHA256 update-Funktion Allgemeine Java-Themen 3
J Methoden Abgeänderte Fibonacci Funktion Allgemeine Java-Themen 2
G Polymorphie Funktion als Parameter Allgemeine Java-Themen 8
F Funktion nur in einem Zeitraum Allgemeine Java-Themen 5
H java.util.Timer und Funktion mit SQL Exception Allgemeine Java-Themen 5
M Anzahl der Durchläufe einer Funktion errechnen Allgemeine Java-Themen 6
J Autofill Funktion Uhrzeit Allgemeine Java-Themen 19
G Timeout funktion zu einer Eventlogabfrage Allgemeine Java-Themen 2
M Funktion gesucht: Text vektorisieren Allgemeine Java-Themen 20
K Warum wartet diese Funktion auf beenden des Threads? Allgemeine Java-Themen 3
N JNI Callback Funktion Allgemeine Java-Themen 8
D Problem bei der Darstellung einer trigonometrischen Funktion Allgemeine Java-Themen 2
E Funktion sperren bis Unterfunktionen ferig sind Allgemeine Java-Themen 3
D Referenz einer Funktion aus einer anonymen Klasse? Allgemeine Java-Themen 3
J Funktion zu einer Uhrzeit/datum ausführen Allgemeine Java-Themen 4
S eigene Update Funktion Allgemeine Java-Themen 5
Ark Name für Funktion gesucht Allgemeine Java-Themen 5
Screen Eine mathematische Funktion als Argument für eine Methode - Matheparser? Allgemeine Java-Themen 21
Daniel_L Bug in Copy-Funktion bei HTML-Editorpane? Allgemeine Java-Themen 4
multiholle Aufrufer einer Funktion ermitteln Allgemeine Java-Themen 13
W JMF- Player.getDuration() Funktion spinnt Allgemeine Java-Themen 2
C JTextComponent - mit Schlagwörter Funktion aufrufen Allgemeine Java-Themen 2
SuperSeppel13 php-funktion aufrufen Allgemeine Java-Themen 5
M get Funktion von Vector Allgemeine Java-Themen 4
V Wie Enum an Funktion "übergeben" ? Allgemeine Java-Themen 4
G Webserver Funktion Allgemeine Java-Themen 3
S Random funktion in einer Grafischen Oberfläche Allgemeine Java-Themen 10
C Funktion stoppt alles Allgemeine Java-Themen 7
G Funktion aus array aufrufen Allgemeine Java-Themen 16
P Funktion vorhanden - wie auf Transitivität erweitern? Allgemeine Java-Themen 6
N Funktion als Parameter einer anderen Funktion Allgemeine Java-Themen 5
lumo Row Header ist public, zeigt die funktion aber nicht public Allgemeine Java-Themen 8
P Unterschied zwischen Funktion und Methoden Allgemeine Java-Themen 3
B E-Funktion mit Java Allgemeine Java-Themen 9
S verstehe diese Funktion nicht Allgemeine Java-Themen 6
S Referenz auf Funktion? Allgemeine Java-Themen 16
K Funktion unabhängig vom Namen aufrufen Allgemeine Java-Themen 5
F Vorteile -> Funktion Allgemeine Java-Themen 2
P gegenstück zur php funktion gzinflate()? Allgemeine Java-Themen 3
D Problem bei Aufruf einer Funktion Allgemeine Java-Themen 3
J Welche Daten für Ative-X Funktion? Allgemeine Java-Themen 5
X Replay Funktion realisieren? Allgemeine Java-Themen 5
J Funktion alle Möglichkeiten berücksichtigen Allgemeine Java-Themen 5
P DLL Funktion benutzen Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben