Es gibt kein static
Schlüsselwort in Kotlin.
Wie lässt sich eine static
Java-Methode in Kotlin am besten darstellen ?
Es gibt kein static
Schlüsselwort in Kotlin.
Wie lässt sich eine static
Java-Methode in Kotlin am besten darstellen ?
Antworten:
Sie platzieren die Funktion im "Begleitobjekt".
Also der Java-Code wie folgt:
class Foo {
public static int a() { return 1; }
}
wird werden
class Foo {
companion object {
fun a() : Int = 1
}
}
Sie können es dann aus dem Kotlin-Code als verwenden
Foo.a();
Aber innerhalb von Java-Code müssten Sie es als aufrufen
Foo.Companion.a();
(Was auch innerhalb von Kotlin funktioniert.)
Wenn Sie das Companion
Bit nicht angeben müssen , können Sie entweder eine @JvmStatic
Anmerkung hinzufügen oder Ihre Begleitklasse benennen.
Aus den Dokumenten :
Begleitobjekte
Eine Objektdeklaration innerhalb einer Klasse kann mit dem Schlüsselwort Companion gekennzeichnet werden:
class MyClass { companion object Factory { fun create(): MyClass = MyClass() } }
Mitglieder des Begleitobjekts können aufgerufen werden, indem einfach der Klassenname als Qualifikationsmerkmal verwendet wird:
val instance = MyClass.create()
...
In der JVM können jedoch Mitglieder von Begleitobjekten als echte statische Methoden und Felder generiert werden, wenn Sie die
@JvmStatic
Anmerkung verwenden. Weitere Informationen finden Sie im Abschnitt zur Java-Interoperabilität.
Das Hinzufügen der @JvmStatic
Anmerkung sieht folgendermaßen aus
class Foo {
companion object {
@JvmStatic
fun a() : Int = 1;
}
}
und dann wird es als echte statische Java-Funktion existieren, auf die sowohl von Java als auch von Kotlin als zugegriffen werden kann Foo.a()
.
Wenn der Companion
Name nur nicht gefällt, können Sie auch einen expliziten Namen für das Begleitobjekt angeben, der folgendermaßen aussieht:
class Foo {
companion object Blah {
fun a() : Int = 1;
}
}
Damit können Sie es von Kotlin auf die gleiche Weise aufrufen, aber von Java-ähnlich Foo.Blah.a()
(was auch in Kotlin funktioniert).
fun a(): Int { return 1 }
oder sogarfun a(): Int = 1
fun a() = 1
.
Factory
ist der Name des Begleitobjekts - aber wofür kann das verwendet werden? Ich habe keine Ahnung, aber ich war interessiert, also habe ich eine Frage dazu erstellt: stackoverflow.com/q/45853459/221955 .
Docs empfiehlt für statische Funktionen mit dem meisten Bedürfnissen zu lösen Funktionen auf Paketebene . Sie werden einfach außerhalb einer Klasse in einer Quellcodedatei deklariert. Das Paket einer Datei kann am Anfang einer Datei mit dem Schlüsselwort package angegeben werden.
Erklärung
package foo
fun bar() = {}
Verwendungszweck
import foo.bar
Alternative
import foo.*
Sie können die Funktion jetzt aufrufen mit:
bar()
oder wenn Sie das Schlüsselwort import nicht verwenden:
foo.bar()
Wenn Sie das Paket nicht angeben, kann auf die Funktion über das Stammverzeichnis zugegriffen werden.
Wenn Sie nur Erfahrung mit Java haben, scheint dies ein wenig seltsam. Der Grund ist, dass Kotlin keine streng objektorientierte Sprache ist. Man könnte sagen, es unterstützt Methoden außerhalb von Klassen.
Bearbeiten: Sie haben die Dokumentation so bearbeitet, dass sie den Satz über die Empfehlung von Funktionen auf Paketebene nicht mehr enthält. Dies ist das Original, auf das oben Bezug genommen wurde.
class FooPackage
mit allen Eigenschaften und Funktionen der obersten Ebene erstellen und alle Ihre Verweise entsprechend an diese weiterleiten. Weitere Infos von Jetbrains.
bar()
, der Dateiname keine Rolle spielt, Sie sie benennen können BarUtils.kt
oder was auch immer, dann, wie der Text sagt, werden Sie sie mit importierenimport <package name>.bar
A. Alter Java-Weg:
Deklarieren Sie a companion object
, um eine statische Methode / Variable einzuschließen
class Foo{
companion object {
fun foo() = println("Foo")
val bar ="bar"
}
}
Verwenden :
Foo.foo() // Outputs Foo
println(Foo.bar) // Outputs bar
B. Neuer Kotlin-Weg
Deklarieren Sie direkt in einer Datei ohne Klasse in einer .kt
Datei.
fun foo() = println("Foo")
val bar ="bar"
Verwenden Sie die methods/variables
mit ihren Namen . ( Nach dem Import )
Verwenden :
foo() // Outputs Foo
println(bar) // Outputs bar
INSTANCE
Schlüsselwort haben, wie Foo.INSTANCE.sayFoo()
static CLASS
nicht nur wollen static methdos
. Denn mit Begleitobjekten können Sie die übergeordnete Klasse weiterhin instanziieren.
val
ist nicht statisch, es entspricht static final
Java
Verwenden Sie object , um val / var / method darzustellen und statisch zu machen. Sie können auch ein Objekt anstelle einer Singleton-Klasse verwenden. Sie können Companion verwenden, wenn Sie innerhalb einer Klasse statisch machen möchten
object Abc{
fun sum(a: Int, b: Int): Int = a + b
}
Wenn Sie es von Java aus aufrufen müssen:
int z = Abc.INSTANCE.sum(x,y);
Ignorieren Sie in Kotlin INSTANCE.
object objectName {
fun funName() {
}
}
Sie müssen das Begleitobjekt für die statische Methode übergeben, da kotlin kein statisches Schlüsselwort hat. Mitglieder des Begleitobjekts können aufgerufen werden, indem einfach der Klassenname als Qualifikationsmerkmal verwendet wird:
package xxx
class ClassName {
companion object {
fun helloWord(str: String): String {
return stringValue
}
}
}
Es gibt zwei Möglichkeiten, wie Sie statisch in Kotlin anwenden können
Erstellen Sie zuerst ein Begleitobjekt unter Klasse
Zum Beispiel:
class Test{
companion object{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
}
Sie können diese Funktion als aufrufen
Test.Companion.isCheck(2)
Eine andere Möglichkeit besteht darin, eine Objektklasse zu erstellen
object Test{
fun isCheck(a:Int):Boolean{
if(a==0) true else false
}
}
Viel Spaß beim Codieren!
Test.Companion.isCheck(2)
) zeigt IDE Warnungen an und sagt Companion reference is redundant
. Es kann auf reduziert werden Test.isCheck(2)
und die reduzierte Form kommt dem Java-Äquivalent näher.
Kotlin hat kein statisches Schlüsselwort. Du hast das für Java benutzt
class AppHelper {
public static int getAge() {
return 30;
}
}
und für Kotlin
class AppHelper {
companion object {
fun getAge() : Int = 30
}
}
Rufen Sie nach Java
AppHelper.getAge();
Rufen Sie nach Kotlin
AppHelper.Companion.getAge();
Ich denke, es funktioniert perfekt.
Ich möchte den obigen Antworten etwas hinzufügen.
Ja, Sie können Funktionen in Quellcodedateien (außerhalb der Klasse) definieren. Es ist jedoch besser, wenn Sie statische Funktionen innerhalb der Klasse mit Companion Object definieren, da Sie durch Nutzung der Kotlin-Erweiterungen weitere statische Funktionen hinzufügen können .
class MyClass {
companion object {
//define static functions here
}
}
//Adding new static function
fun MyClass.Companion.newStaticFunction() {
// ...
}
Sie können die oben definierte Funktion aufrufen, da Sie jede Funktion in Companion Object aufrufen.
Obwohl dies jetzt etwas mehr als 2 Jahre alt ist und viele gute Antworten hatte, sehe ich, dass einige andere Möglichkeiten, "statische" Kotlin-Felder zu erhalten, fehlen. Hier ist eine Beispielanleitung für Kotlin-Java static
Interop:
Szenario 1: Erstellen einer statischen Methode in Kotlin für Java
Kotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Java classes to treat this method as if it was a static to [KotlinClass] @JvmStatic fun foo(): Int = 1 //Without it, you would have to use [KotlinClass.Companion.bar()] to use this method. fun bar(): Int = 2 } }
Java
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo()); //Prints "1" println(KotlinClass.Companion.bar()); //Prints "2". This is the only way to use [bar()] in Java. println(KotlinClass.Companion.foo()); //To show that [Companion] is still the holder of the function [foo()] } //Because I'm way to lazy to keep typing [System.out], but I still want this to be compilable. void println(Object o) { System.out.println(o); } }
Michael Andersons Antwort bietet mehr Tiefe als diese und sollte für dieses Szenario definitiv referenziert werden.
In diesem nächsten Szenario werden statische Felder in Kotlin erstellt, damit Java nicht ständig KotlinClass.foo()
nach Fällen aufrufen muss, in denen Sie keine statische Funktion wünschen.
Szenario 2: Erstellen einer statischen Variablen in Kotlin für Java
Kotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits class KotlinClass { companion object { //This annotation tells Kotlin to not generate the getter/setter functions in Java. Instead, this variable should be accessed directly //Also, this is similar to [@JvmStatic], in which it tells Java to treat this as a static variable to [KotlinClass]. @JvmField var foo: Int = 1 //If you want something akin to [final static], and the value is a primitive or a String, you can use the keyword [const] instead //No annotation is needed to make this a field of [KotlinClass]. If the declaration is a non-primitive/non-String, use @JvmField instead const val dog: Int = 1 //This will be treated as a member of the [Companion] object only. It generates the getter/setters for it. var bar: Int = 2 //We can still use [@JvmStatic] for 'var' variables, but it generates getter/setters as functions of KotlinClass //If we use 'val' instead, it only generates a getter function @JvmStatic var cat: Int = 9 } }
Java
package com.frybits; class JavaClass { void someFunction() { //Example using @JvmField println(KotlinClass.foo); //Prints "1" KotlinClass.foo = 3; //Example using 'const val' println(KotlinClass.dog); //Prints "1". Notice the lack of a getter function //Example of not using either @JvmField, @JvmStatic, or 'const val' println(KotlinClass.Companion.getBar()); //Prints "2" KotlinClass.Companion.setBar(3); //The setter for [bar] //Example of using @JvmStatic instead of @JvmField println(KotlinClass.getCat()); KotlinClass.setCat(0); } void println(Object o) { System.out.println(o); } }
Eine der großartigen Funktionen von Kotlin ist, dass Sie Funktionen und Variablen der obersten Ebene erstellen können. Dies macht es großartig, "klassenlose" Listen konstanter Felder und Funktionen zu erstellen, die wiederum als static
Funktionen / Felder in Java verwendet werden können.
Szenario 3: Zugriff auf Felder und Funktionen der obersten Ebene in Kotlin von Java aus
Kotlin
//In this example, the file name is "KSample.kt". If this annotation wasn't provided, all functions and fields would have to accessed //using the name [KSampleKt.foo()] to utilize them in Java. Make life easier for yourself, and name this something more simple @file:JvmName("KotlinUtils") package com.frybits //This can be called from Java as [KotlinUtils.TAG]. This is a final static variable const val TAG = "You're it!" //Since this is a top level variable and not part of a companion object, there's no need to annotate this as "static" to access in Java. //However, this can only be utilized using getter/setter functions var foo = 1 //This lets us use direct access now @JvmField var bar = 2 //Since this is calculated at runtime, it can't be a constant, but it is still a final static variable. Can't use "const" here. val GENERATED_VAL:Long = "123".toLong() //Again, no need for @JvmStatic, since this is not part of a companion object fun doSomethingAwesome() { println("Everything is awesome!") }
Java
package com.frybits; class JavaClass { void someFunction() { println(KotlinUtils.TAG); //Example of printing [TAG] //Example of not using @JvmField. println(KotlinUtils.getFoo()); //Prints "1" KotlinUtils.setFoo(3); //Example using @JvmField println(KotlinUtils.bar); //Prints "2". Notice the lack of a getter function KotlinUtils.bar = 3; //Since this is a top level variable, no need for annotations to use this //But it looks awkward without the @JvmField println(KotlinUtils.getGENERATED_VAL()); //This is how accessing a top level function looks like KotlinUtils.doSomethingAwesome(); } void println(Object o) { System.out.println(o); } }
Eine weitere bemerkenswerte Erwähnung, die in Java als "statische" Felder verwendet werden kann, sind Kotlin- object
Klassen. Dies sind Nullparameter-Singleton-Klassen, die bei der ersten Verwendung träge instanziiert werden. Weitere Informationen dazu finden Sie hier: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations
Für den Zugriff auf den Singleton wird jedoch ein spezielles INSTANCE
Objekt erstellt, dessen Handhabung genauso umständlich Companion
ist wie es ist. So verwenden Sie Anmerkungen, um static
Java ein sauberes Gefühl zu verleihen :
Szenario 4: Verwenden von
object
KlassenKotlin
@file:JvmName("KotlinClass") //This provides a name for this file, so it's not defaulted as [KotlinClassKt] in Java package com.frybits object KotlinClass { //No need for the 'class' keyword here. //Direct access to this variable const val foo: Int = 1 //Tells Java this can be accessed directly from [KotlinClass] @JvmStatic var cat: Int = 9 //Just a function that returns the class name @JvmStatic fun getCustomClassName(): String = this::class.java.simpleName + "boo!" //Getter/Setter access to this variable, but isn't accessible directly from [KotlinClass] var bar: Int = 2 fun someOtherFunction() = "What is 'INSTANCE'?" }
Java
package com.frybits; class JavaClass { void someFunction() { println(KotlinClass.foo); //Direct read of [foo] in [KotlinClass] singleton println(KotlinClass.getCat()); //Getter of [cat] KotlinClass.setCat(0); //Setter of [cat] println(KotlinClass.getCustomClassName()); //Example of using a function of this 'object' class println(KotlinClass.INSTANCE.getBar()); //This is what the singleton would look like without using annotations KotlinClass.INSTANCE.setBar(23); println(KotlinClass.INSTANCE.someOtherFunction()); //Accessing a function in the object class without using annotations } void println(Object o) { System.out.println(o); } }
Um es kurz zu machen, könnten Sie "Companion Object" verwenden , um in die statische Welt von Kotlin zu gelangen, wie:
companion object {
const val TAG = "tHomeFragment"
fun newInstance() = HomeFragment()
}
und um ein konstantes Feld zu erstellen, verwenden Sie "const val" wie im Code. Vermeiden Sie jedoch die statischen Klassen, da dies beim Testen von Einheiten mit Mockito! zu Schwierigkeiten führt.
Die genaue Konvertierung der statischen Java-Methode in ein Kotlin-Äquivalent wäre wie folgt. zB Hier hat die util-Klasse eine statische Methode, die sowohl in Java als auch in Kotlin gleichwertig wäre. Die Verwendung von @JvmStatic ist wichtig.
Java-Code:
class Util{
public static String capitalize(String text){
return text.toUpperCase();}
}
Kotlin-Code:
class Util {
companion object {
@JvmStatic
fun capitalize(text:String): String {
return text.toUpperCase()
}
}
}
Sie müssen lediglich ein Begleitobjekt erstellen und die Funktion darin einfügen
class UtilClass {
companion object {
// @JvmStatic
fun repeatIt5Times(str: String): String = str.repeat(5)
}
}
So rufen Sie die Methode aus einer Kotlin-Klasse auf:
class KotlinClass{
fun main(args : Array<String>) {
UtilClass.repeatIt5Times("Hello")
}
}
oder Import verwenden
import Packagename.UtilClass.Companion.repeatIt5Times
class KotlinClass{
fun main(args : Array<String>) {
repeatIt5Times("Hello")
}
}
So rufen Sie die Methode von einer Java-Klasse aus auf:
class JavaClass{
public static void main(String [] args){
UtilClass.Companion.repeatIt5Times("Hello");
}
}
oder indem Sie der Methode die Annotation @JvmStatic hinzufügen
class JavaClass{
public static void main(String [] args){
UtilClass.repeatIt5Times("Hello")
}
}
oder beides, indem Sie der Methode eine @ JvmStatic-Annotation hinzufügen und einen statischen Import in Java durchführen
import static Packagename.UtilClass.repeatIt5Times
class JavaClass{
public static void main(String [] args){
repeatIt5Times("Hello")
}
}
Für Java:
public class Constants {
public static final long MAX_CLICK_INTERVAL = 1000;}
Äquivalenter Kotlin-Code:
object Constants {
const val MAX_CLICK_INTERVAL: Long = 1000}
Das Äquivalent zu statischen Java-Methoden ist also die Objektklasse in Kotlin.
Für Android wird eine Zeichenfolge von einer einzelnen Aktivität bis zu allen erforderlichen Aktivitäten verwendet. Genau wie statisch in Java
public final static String TEA_NAME = "TEA_NAME";
Gleichwertiger Ansatz in Kotlin:
class MainActivity : AppCompatActivity() {
companion object {
const val TEA_NAME = "TEA_NAME"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Eine weitere Aktivität, bei der Wert benötigt wird:
val teaName = MainActivity.TEA_NAME
Mit Ausnahme von Michael Andersons Antwort habe ich in meinem Projekt Codierung mit anderen zwei Möglichkeiten.
Sie können alle Variablen einer Klasse zuordnen. hat eine Kotlin-Datei namens Const erstellt
object Const {
const val FIRST_NAME_1 = "just"
const val LAST_NAME_1 = "YuMu"
}
Sie können es in Kotlin- und Java-Code verwenden
Log.d("stackoverflow", Const.FIRST_NAME_1)
Sie können die Erweiterungsfunktion von Kotlin verwenden, mit der
eine Kotlin-Datei mit dem Namen Ext erstellt wurde. Unter Code ist der gesamte Code in der Ext-Datei
package pro.just.yumu
/**
* Created by lpf on 2020-03-18.
*/
const val FIRST_NAME = "just"
const val LAST_NAME = "YuMu"
Sie können es in Kotlin-Code verwenden
Log.d("stackoverflow", FIRST_NAME)
Sie können es in Java-Code verwenden
Log.d("stackoverflow", ExtKt.FIRST_NAME);
Schreiben Sie sie direkt in Dateien.
In Java (hässlich):
package xxx;
class XxxUtils {
public static final Yyy xxx(Xxx xxx) { return xxx.xxx(); }
}
In Kotlin:
@file:JvmName("XxxUtils")
package xxx
fun xxx(xxx: Xxx): Yyy = xxx.xxx()
Diese beiden Codeteile werden nach der Kompilierung gleichgestellt (selbst der kompilierte Dateiname file:JvmName
wird verwendet, um den kompilierten Dateinamen zu steuern, der unmittelbar vor der Deklaration des Paketnamens stehen sollte).
Verwenden Sie @JVMStatic
Annotation
companion object {
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
EditProfileFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
Lassen Sie, Sie haben eine Klasse Student . Und Sie haben eine statische Methode getUniversityName () und ein statisches Feld namens totalStudent .
Sie sollten den Begleitobjektblock in Ihrer Klasse deklarieren .
companion object {
// define static method & field here.
}
Dann sieht deine Klasse aus wie
class Student(var name: String, var city: String, var rollNumber: Double = 0.0) {
// use companion object structure
companion object {
// below method will work as static method
fun getUniversityName(): String = "MBSTU"
// below field will work as static field
var totalStudent = 30
}
}
Dann können Sie diese statischen Methoden und Felder auf diese Weise verwenden.
println("University : " + Student.getUniversityName() + ", Total Student: " + Student.totalStudent)
// Output:
// University : MBSTU, Total Student: 30
In Kotlin gibt es kein statisches Schlüsselwort. kotlin docs empfiehlt die Verwendung von Funktionen auf Paketebene, wenn Sie DRY folgen möchten. Erstellen Sie eine Datei mit der Erweiterung .kt und fügen Sie Ihre Methode ein.
package p
fun m(){
//fun body
}
Nach der Kompilierung hat m eine Signatur der öffentlichen statischen endgültigen Leere
und
import p.m
☺
Sie können die statische Funktionalität in Kotlin von Companion Objects erreichen
Ein Begleitobjekt kann nicht außerhalb der Klasse deklariert werden.
class MyClass{
companion object {
val staticField = "This is an example of static field Object Decleration"
fun getStaticFunction(): String {
return "This is example of static function for Object Decleration"
}
}
}
Mitglieder des Begleitobjekts können aufgerufen werden, indem einfach der Klassenname als Qualifikationsmerkmal verwendet wird:
Ausgabe:
MyClass.staticField // This is an example of static field Object Decleration
MyClass.getStaticFunction() : // This is an example of static function for Object Decleration
Viele Leute erwähnen Begleitobjekte, was richtig ist. Aber nur damit Sie wissen, können Sie auch jede Art von Objekt verwenden (mit dem Objektschlüsselwort, nicht mit der Klasse), dh
object StringUtils {
fun toUpper(s: String) : String { ... }
}
Verwenden Sie es wie jede statische Methode in Java:
StringUtils.toUpper("foobar")
Diese Art von Muster ist in Kotlin jedoch nutzlos. Eine seiner Stärken besteht darin, dass keine Klassen mit statischen Methoden mehr benötigt werden. Abhängig von Ihrem Anwendungsfall ist es besser, stattdessen globale, Erweiterungs- und / oder lokale Funktionen zu verwenden. Wo ich arbeite, definieren wir häufig globale Erweiterungsfunktionen in einer separaten, flachen Datei mit der Namenskonvention: [className] Extensions.kt, dh FooExtensions.kt. Typischerweise schreiben wir Funktionen jedoch dort, wo sie innerhalb ihrer Betriebsklasse oder ihres Objekts benötigt werden.
In Java können wir unten schreiben
class MyClass {
public static int myMethod() {
return 1;
}
}
In Kotlin können wir unten schreiben
class MyClass {
companion object {
fun myMethod() : Int = 1
}
}
Ein Begleiter wird in Kotlin als statisch verwendet.
Der Kotlin-Dokumentanbieter bietet drei Möglichkeiten, um dies zu tun. Die erste besteht darin, die Funktion im Paket ohne Klasse zu definieren:
package com.example
fun f() = 1
Die zweite ist die Verwendung der Annotation @JvmStatic:
package com.example
class A{
@JvmStatic
fun f() = 1
}
und das dritte ist das Begleitobjekt verwenden:
package com.example
clss A{
companion object{
fun f() = 1
}
}
Wenn Sie eine Funktion oder Eigenschaft benötigen, die an eine Klasse und nicht an Instanzen derselben gebunden werden soll, können Sie sie in einem Begleitobjekt deklarieren:
class Car(val horsepowers: Int) {
companion object Factory {
val cars = mutableListOf<Car>()
fun makeCar(horsepowers: Int): Car {
val car = Car(horsepowers)
cars.add(car)
return car
}
}
}
Das Begleitobjekt ist ein Singleton, und auf seine Mitglieder kann direkt über den Namen der enthaltenen Klasse zugegriffen werden
val car = Car.makeCar(150)
println(Car.Factory.cars.size)
Sie können verwenden Companion Objects - kotlinlang verwenden
Was gezeigt werden kann, indem zuerst diese Schnittstelle erstellt wird
interface I<T> {
}
Dann müssen wir eine Funktion innerhalb dieser Schnittstelle erstellen:
fun SomeFunc(): T
Danach brauchen wir eine Klasse:
class SomeClass {}
Innerhalb dieser Klasse benötigen wir ein Begleitobjekt innerhalb dieser Klasse:
companion object : I<SomeClass> {}
In diesem Begleitobjekt brauchen wir diese alte SomeFunc
Funktion, aber wir müssen sie überschreiben:
override fun SomeFunc(): SomeClass = SomeClass()
Schließlich brauchen wir unter all dieser Arbeit etwas, um diese statische Funktion zu stärken. Wir brauchen eine Variable:
var e:I<SomeClass> = SomeClass()