3

On possible duplicate:

This thread is not asking how to extend a final class. It is asking why a class declared as final could possibly extend another class.


From this thread:

A final class is simply a class that can't be extended.

However, I have a helper class which I declared to be final and extends another class:

public final class PDFGenerator extends PdfPageEventHelper {
    private static Font font;

    private PDFGenerator() {
        // prevent instantiation
    }

    static {
        try {
            BaseFont baseFont = BaseFont.createFont(
                "/Trebuchet MS.ttf",
                BaseFont.WINANSI,
                BaseFont.EMBEDDED
            );

            font = new Font(baseFont, 9);

        } catch(DocumentException de) { 
            de.printStackTrace();

        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public static ByteArrayOutputStream generatePDF() throws DocumentException {            
        Document doc = new Document();
        ByteArrayOutputStream baosPDF = new ByteArrayOutputStream();        
        PdfWriter pdfWriter = PdfWriter.getInstance(doc, baosPDF);

        try {           
            // create pdf

        } catch(DocumentException de) {
            baosPDF.reset();
            throw de;

        } finally {
            if(doc != null) {
                doc.close();
            }

            if(pdfWriter != null) {
                pdfWriter.close();
            }
        }

        return baosPDF;
    }
}

Eclipse does not detect anything wrong with it. I have tested the class and the PDF was successfully generated without error.

Why was I able to extend a final class when I should not be able to in theory?

(I am using Java 7 if that matters.)

Community
  • 1
  • 1
k_rollo
  • 5,304
  • 16
  • 63
  • 95
  • 6
    Try *extending* `PDFGenerator `. A final class can extend classes but it cannot be extended by other classes – TheLostMind May 06 '15 at 07:22
  • Possible duplicate of: http://stackoverflow.com/questions/13294629/how-to-extend-a-final-class-in-java –  May 06 '15 at 07:23
  • 1
    A `final` class that extends another class is not the same thing as another class that extends a `final` class - it's exactly the other way around. – Jesper May 06 '15 at 07:24
  • Probably, it's problem with English, not with Java :-) – Dmitry Ginzburg May 13 '15 at 09:47

8 Answers8

11

A Class marked as final can extend another Class, however a final Class can not be extended.

Here is an example:

This is allowed

public class Animal {

}

public final class Cat extends Animal {

}

This is not allowed

public final class Animal {

}

public class Cat extends Animal {

}
KernelKoder
  • 746
  • 5
  • 15
2

PDFGenerator cannot be extended as it is marked final. You are extending PdfPageEventHelper which is not marked final.

Brett Walker
  • 3,566
  • 1
  • 18
  • 36
1

It seems to me, that PdfPageEventHelper is not final (and this javadoc confirms it), so you can extend it, still you can't extend this new class PDFGenerator.

You may try to do it, though:

private Object abacaba = new PDFGenerator() {
};

Then you'll get compilation error:

BlahBlah.java:n: error: cannot inherit from final PDFGenerator

Dmitry Ginzburg
  • 7,391
  • 2
  • 37
  • 48
1

Why was I able to extend a final class when I should not be able to in theory?

You weren't. your final class extended another class, it wasn't extended itself.

final classes (String is an example) are 'protected' against being inherited. You can not extend them.

In your example, try creating a new class, that does extend your final class:

public class A extends PDFGenerator{}

and see what happens.

Stultuske
  • 9,296
  • 1
  • 25
  • 37
1

Note that PDFGenerator extends PdfPageEventHelper. That means that PDFGenerator is final but PdfPageEventHelper is not a final class. If you try to extend the PDFGenerator, then you will get exceptions if not errors.

Patrick W
  • 1,485
  • 4
  • 19
  • 27
  • Error or exception comes when your program runs. If you try to extend a final class, your code will not even compile. – Aakash May 06 '15 at 07:28
1

PdfPageEventHelper class is not made as final and hence you are able to extend that class. The final class cannot be extended.

If you try to extend PDFGenerator class which you have made as final then you will see that you are not able to extend that as its marked final.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
1

You have extended the PdfPageEventHelper (It must not be final i'm sure), PDFGenerator is decleared as final so the class PDFGenerator can't be extended by any class.Try extending PDFGenerator you won't be able to extend.

Anand Kadhi
  • 1,790
  • 4
  • 27
  • 40
0

No and defiantly not, final keyword is known in java as is used to restrict the user. It can be applied on variable method and class;

Constant Variable: (for all primtive and String) If you make any variable as final, you cannot change the value.

Method: If you make any method as final, you cannot override it.

Class: If you make any class as final, you cannot extend it.

It totally depends on requirements which object should/must set as final.

Reason of using final: It ensures the thread safety for field/method or class,

Sarz
  • 1,970
  • 4
  • 23
  • 43
  • If you make a PRIMITIVE variable as final, you cannot change the value. if you make an OBJECT final, you can not re-reference it, but in a lot of cases, you will be able to change the value. – Stultuske May 06 '15 at 07:41
  • Yes, I am talking about Constant Variable, As far I know (programming depth is still unknown) this final means the Object should be initialize in same time it get defined. If you make collection you are able to add object but cannot re-initialize. – Sarz May 06 '15 at 07:58
  • a simple pojo as well. as long as all it's members are not final, and provide setters, you'll be able to change it's value. – Stultuske May 06 '15 at 08:00
  • For POJO you need `this.foo = foo` which is not allowed. because you have `final Object foo= this.some();`, isn't it? – Sarz May 06 '15 at 08:10
  • I'll give an example: public class Person(){ private String name; public Person(String name){ this.name = name;} public void setName(String name){ this.name = name;} public String getName(){ return this.name; } public static void main(String[] args){ final Person p = new Person("Bob"); System.out.println(p.getName()); p.setName("Kurt"); System.out.println(p.getName()); }} you change the value, since even though p is final, name is not. – Stultuske May 06 '15 at 08:36
  • We are talking same thing again and again ;), As i mentioned you cannot do `p= new Person("");` again or after define it, because it is final. Read in the answer when you make class as final it means you are restricting it `not being extend` as same case about collections i talked about. – Sarz May 06 '15 at 09:08
  • true, but my responses are based on this comment in your answer: "If you make any variable as final, you cannot change the value." – Stultuske May 06 '15 at 10:26
  • Yes, its for non-primitive! – Sarz May 06 '15 at 11:04
  • when it's not a primitive, you can change it's value. You just can't change it's reference. – Stultuske May 06 '15 at 11:05