2016-10-25 7 views
9

Я изучаю свою BS, и мой профессор дал мне задание, он сказал: Создайте класс без использования какого-либо модификатора доступа или ключевого слова интерфейса, чей объект не может быть создан.Создайте класс, объект которого не может быть создан

Я прошел через Google, но не могу найти решение. Как это можно сделать на Java?

+0

Разве профессор не дал вам никакой дополнительной информации для работы? Определить «невозможно создать». –

+13

«Я студентка BS». Английский не может быть вашим первым языком, но вы, должно быть, знаете, что это довольно смешная интерпретация: «Я студентка bullsh * t». –

+1

Конструкторы могут исключать исключения – JonK

ответ

12

Enums - это классы (JLS§8.9), которые не могут быть созданы и не могут быть подклассифицированы; просто создать без каких-либо значений:

enum Foo {} 

Другие возможности в зависимости от интерпретации:

JonK и T.J. Crowder считается выбрасыванием исключения из конструктора:

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

Но nick zoum отметил, что экземпляр все еще создается и существует, кратко, до исключения, хотя он не может (в примере выше).

nick zoum считается abstract:

abstract class Example { 
} 

... но T.J. Crowder отметил, что abstract классы могут быть подклассы (они не могут быть final), и подкласс экземпляра «является» суперкласс экземпляр.

+0

Я думаю, что это единственное решение, которое на самом деле это делает. JLS вызывает перечисления «[особый тип класса] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9)», и поэтому они являются классами. Но вы не можете подклассифицировать их, вы не можете использовать 'new' с ними, и единственными экземплярами являются их значения. Таким образом, перечисление без значений является классом, который не может быть создан (кроме, возможно, путем манипулирования байт-кодом, который, я думаю, любой разумный человек может согласиться, будет за пределами границ). –

+1

@AndyTurner Не стесняйтесь добавлять свой ответ к себе, как указано TJCrowder –

+0

@nickzoum: Done. :-) –

3

Вы пробовали ключевое слово abstract?

Например:

abstract class Test{} 

Конечно, это может быть перезаписана, поэтому, пожалуйста, проверьте this answer для более Foolproof дизайна.

+2

Я могу создать один из них через подкласс. Помните, что даже экземпляр подкласса - это «Тест». –

+0

Сделайте его окончательным абстрактом, конечные средства не могут быть подклассами, abstract = не могут быть созданы –

+3

@TheresaForster да, попробуйте! –

6

Я не человек, Java, но и другие ответы дали мне эту идею:

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

Я уверен, что нет никакого способа сделать Problematic и выжить ...

(Обратите внимание, что, когда я попытался throw new Exception(); в статическом инициализаторе не компилируется)

+1

В принципе вариант «throw Exception from Constructor» - идея, но на уровне класса вместо уровня экземпляра.И действительно, если вы не можете инициализировать класс, вы не можете создавать экземпляры +1 – Hulk

+1

'throw new RuntimeException();' должен работать в статических инициализаторах – Kapep

+1

@Kapep также получает «Main.java:20: ошибка: инициализатор должен иметь возможность завершить обычно ", то же самое, что и" Исключение " – AakashM

0

Анонимный внутренний класс должен быть ответом.

Пример:

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(); 
    } 
} 

Класс создается, но это название будет принято решение компилятором, который расширяет класс HelloWorld и обеспечивает реализацию метода x().

+2

Чтобы сделать это полезным ответом, вы должны показать код, который делает это. – hyde

+0

публичный абстрактный класс 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(); } } –

+0

Здесь создан класс, но его имя определяется компилятором, который расширяет класс HelloWorld и обеспечивает реализацию метода x(). –

0

Не понимая, как это сказал ваш профессор, «без использования модификатора доступа» может означать, что они пытаются научить вас, как работает модификатор доступа по умолчанию?

В этом случае:

package mypackage.nocreate; 
class MyClass { 
} 

И потом:

package mypackage; 
import mypackage.nocreate.MyClass; 

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

Можно утверждать, что - в исходном коде, по крайней мере, - что не использует модификатор доступа :)

+0

Я думаю, что ограничение «acces-modifer» находится здесь, чтобы предотвратить использование частного конструктора в конечном классе. – Asoub