2016-10-25 5 views
9

Ich studiere für meine BS, und mein Professor hat mir eine Aufgabe gegeben, er sagte: Erstellen Sie eine Klasse ohne Verwendung eines Zugriffsmodifikators oder Interface-Schlüsselwort, dessen Objekt nicht erstellt werden kann.Erstellen einer Klasse, deren Objekt nicht erstellt werden kann

Ich ging durch Google aber kann die Lösung nicht finden. Wie kann dies in Java getan werden?

+0

Hat Ihnen der Professor keine weiteren Informationen gegeben? Definieren Sie "kann nicht erstellt werden". –

+13

"Ich bin ein Student von BS" Englisch ist vielleicht nicht Ihre Muttersprache, aber Sie sollten vielleicht wissen, dass es eine ziemlich lustige Interpretation hat: "Ich bin ein Student von Bullsh * t". –

+1

Konstruktoren können Ausnahmen auslösen – JonK

Antwort

12

Enums sind Klassen (JLS§8.9), die nicht instanziiert werden können und nicht unterklassifiziert werden können; nur erstellen, ohne Werte:

enum Foo {} 

Andere Möglichkeiten, je nach Interpretation:

JonK und T.J. Crowder als eine Ausnahme von dem Konstruktor werfen:

final class Example { 
    Example() { 
     throw new Exception(); 
    } 
} 

Aber nick zoum wiesen darauf hin, dass Eine Instanz wird immer noch erstellt und existiert kurz vor der Ausnahme, obwohl dies nicht möglich ist (im Beispiel) oben) beibehalten werden.

nick zoum betrachtet abstract:

abstract class Example { 
} 

... aber T.J. Crowder wies darauf hin, dass abstract Klassen subclassed werden können (sie sind nicht final sein kann) und eine Unterklasse Instanz "ist eine" Super Instanz.

+0

Ich denke, das ist die einzige Lösung, die es tatsächlich tut. Die JLS ruft Enums "[eine spezielle Klassenart] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9) auf" und somit sind sie Klassen. Aber Sie können sie nicht ableiten, Sie können nicht 'new' mit ihnen verwenden, und die einzigen Instanzen sind ihre Werte. Eine Enumeration ohne Werte ist also eine Klasse, die nicht instanziiert werden kann (außer möglicherweise durch Manipulation von Bytecode, von dem ich denke, dass jede vernünftige Person zustimmen könnte, dass sie außerhalb der Grenzen liegt). –

+1

@AndyTurner Fühlen Sie sich frei, um meine Antwort zu geben, wie von TJCrowder –

+0

@nickcoum angewiesen: Fertig. :-) –

3

Haben Sie das Schlüsselwort abstract versucht?

Zum Beispiel:

abstract class Test{} 

Natürlich ist diese überschrieben werden können, so wenden Sie sich bitte this answer für eine narrensichere Konstruktion überprüfen.

+2

Ich kann eines von denen über eine Unterklasse erstellen. Denken Sie daran, dass sogar eine Unterklasseninstanz "ein" "Test" ist. –

+0

Make es final abstract, Final bedeutet nicht unterklassifiziert, abstract = kann nicht instanziiert werden –

+3

@TheresaForster yeah, probier es aus! –

6

Ich bin kein Java Person, aber auch andere Antworten gab mir diese Idee:

import java.util.*; 
import java.lang.*; 
import java.io.*; 


class Ideone 
{ 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     Object o = new Problematic(); 

     // unreachable 

    } 
} 

class Problematic 
{ 
    static 
    { 
     int i = 1/0 ; 
    } 
} 

Try it on ideone

Ich bin mir ziemlich sicher, dass es keine Möglichkeit, eine Problematic zu machen und zu überleben ...

(Beachten sie, dass, wenn ich throw new Exception(); im statischen Initialisierer versucht würde es nicht kompilieren)

+1

Grundsätzlich eine Variante der "throw Exception from Constructor" - Idee, aber auf Klassenebene statt Instanzebene.Und in der Tat, wenn Sie die Klasse nicht initialisieren können, können Sie keine Instanzen erstellen +1 – Hulk

+1

'throw new RuntimeException();' sollte in statischen Initialisierer funktionieren – Kapep

+1

@Kapep auch bekommt "Main.java:20: Fehler: Initialisierer muss abgeschlossen werden können normalerweise ", das gleiche wie' Exception' – AakashM

0

Anonyme innere Klasse sollte die Antwort sein.

Beispiel:

public abstract class HelloWorld{ 
    abstract void x(); 
    public static void main(String []args){ 
     System.out.println("Hello World"); 
     HelloWorld h = new HelloWorld(){ 
      void x(){ 
       System.out.println(" "); 
      } 
     }; 
     h.x(); 
    } 
} 

Eine Klasse erstellt wird, aber es ist Name vom Compiler bestimmt wird, die die Klasse HelloWorld erstreckt und die Umsetzung der x() Methode.

+2

Um dies zu einer nützlichen Antwort zu machen, sollten Sie Code anzeigen, der dies tut. – hyde

+0

öffentliche abstrakte Klasse HelloWorld { abstract void x(); public static void main (Zeichenfolge [] args) { System.out.println ("Hello World"); HelloWorld h = neu HelloWorld() {void x() {System.out.println ("");}}; h.x(); } } –

+0

Hier Eine Klasse wird erstellt, aber ihr Name wird vom Compiler entschieden, der die HelloWorld-Klasse erweitert und die Implementierung der x() -Methode bereitstellt. –

0

Ohne genau zu hören, wie Ihr Professor es formulierte, "ohne Access-Modifier zu verwenden" könnte bedeuten, dass Sie versuchen, Ihnen beizubringen, wie der "Standard" Zugriffsmodifikator funktioniert?

In diesem Fall:

package mypackage.nocreate; 
class MyClass { 
} 

Und dann:

package mypackage; 
import mypackage.nocreate.MyClass; 

public class Test { 
    public static void main(String[] args) { 
     new MyClass(); // not allowed - in a different package 
    } 
} 

Man könnte argumentieren, dass - im Quellcode zumindest -, die keinen Zugriffsmodifizierer nicht verwendet :)

+0

Ich denke, die Einschränkung "acces-modifer" verhindert hier die Verwendung eines privaten Konstruktors für eine letzte Klasse. – Asoub

Verwandte Themen