Java HiddenFeaturesTraquitanas  escondidas ou simplesmente pouco usadas no Java
São “features” pouco usadas do JavaNenhuma featureé escondida, apenas obscura, desconhecidaAlgumas delas são bem esquisitasMuitas consideradas até mesmo impossíveisUse com cautelaEm alguns casos, são facilidadesPorém, em outros, deixam as coisas mais complicadas.Podem piorar, por exemplo, a legibilidadeO que são HiddenFeatures
Uma das formas mais estranhas de se criar um Map inicializado é através da Double BraceInitialization.Ex: Double BraceInitializationMapmap = newHashMap() {{  put("a key", "a value");  put("anotherkey", "anothervalue");  }}; Veja mais: 	http://www.c2.com/cgi/wiki?DoubleBraceInitialization
WTF?Classes internas anônimas que herda de HashMapPortanto, herda métodos como put()Bloco de inicializaçãoChamado logo após a chamada a super()Em um construtor sem o “super”, passa a impressão de eu é chamado antes do construtorPode ser usado para agrupar lógica usada por vários construtoresÉ legal, mas evite!Double BraceInitialization
Uma adição do Java 1.5 ainda pouco conhecida (ou percebida)Um método sobrescrito pode retornar uma subclasse da classe retornada pelo método da superclasse (ou interface)Necessário para o funcionamento de genericsCovariantReturnclass Super {Collection<String> values() {        ...    }}classSubClassextends Super {    @OverrideList<String> values() {        ...    }}
Quer lançar uma NullPointerException?Lançando NullPointerExcenptionpublicvoidmandaNullNaCara() {thrownull;}Como assim? O compilador pirou? Tá cobrando propina pra deixar isso passar?
A instrução throw, ao ser processada, avalia a expressão à direita. Se a expressão gera um Throwable, este é lançadoEx: throwgetException()Se a expressão completa normalmente, produzindo um valor não nulo, retorna esse valorEx: thrownewSograEmCasaException()Se a expressão resulta em null, o null é convertido para NullpointerException!Lançando NullPointerExcenptionVeja mais:	http://www.adarshr.com/papers/npe	http://java.sun.com/docs/books/jls/
Quer tirar uma exceção lançada de campo?Faz o return no finally!O código abaixo não lança a exceçãoBrincando com finallypublic static void fazAlgumaCoisa() {    try {      //Fazalgumacoisa…      throw new RuntimeException();    } finally {      return;    }  }
Quem for pego fazendo isso vai sofrer vudu reverso!Um erro é para ser tratado ou lançado, nunca escondido!AtençãoVeja Mais: 	http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
Como lançar uma exceção CHECADA de um método que não declara exceção!Agora mais bizarro ainda!importjava.rmi.RemoteException;classThrower {publicstaticvoidspit(final Throwable exception) {classEvilThrower<T extendsThrowable> {      @SuppressWarnings("unchecked")privatevoidsneakyThrow(Throwable exception) throws T {throw (T) exception;      }    }newEvilThrower<RuntimeException>().sneakyThrow(exception);  }}
Agora mais bizarro ainda!publicclassThrowerSample {publicstaticvoidmain( String[] args ) {Thrower.spit(newRemoteException("gounchecked!"));    }}Mim não gostar de lançar exceção assim!
Java não tem goto, mas...LabeledBlocksQuero ver isso funcionar!// codigosaifora:{    for (int i = 0; i < N; ++i) {        for (int j = i; j < N; ++j) {            for (int k = j; k < N; ++k) {//mais código pogbreaksaifora;            }        }    }}
LabeledBlockspublicstatic String getErrorMsg(String _data){    String _errMsg = “”;     VALIDATION:    {        if (_data.length() > 10)        {            _errMsg = “ERR: Data lengthexceed 10 chars”;            break VALIDATION;        }        // Resto docódigo de validação    }     // Tratamento da mensagem de erro    if (_errMsg.length() != 0)    {        _errMsg += “\nPleasefixtheerror.”;     }     return _errMsg;} Problem?
Muita gente não sabe, mas enums podem:Ter MétodosTer AtributosTer ConstrutoresImplementar interfacesEnumVeja mais:http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
EnumenumCaes{MINOTAURO(2), TITAN(3), SADAM(7);privateintidade;Caes(int idade) {this.idade = idade;  }publicintgetIdade() {returnidade;}}
EnumpublicenumSalas implements Sala{PRIMEIRA{publicSala norte() {returnSEGUNDA;      }   },SEGUNDA{publicSala sul() {returnPRIMEIRA;      }   }publicSala norte() { returnnull; }public Sala sul() { returnnull; }public Sala lest() { returnnull; }public Sala oeste() { returnnull; }}public interface Sala{public Sala norte();public Sala sul();public Sala leste();public Sala oeste();}
Desde a versão 1.5, o Java aceita parâmetros variáveisVar argspublicvoidfoo(String... bars) {   for (String bar: bars)      System.out.println(bar);}publicvoidtest() {foo("first","second","third")}
Printf e String.formatPrintf do entrou na versão 1.5String.format funciona analogamente, mas retorna ao invés de imprimirdouble x = 27.5;doubley = 33.75;System.out.printf("x = %f y = %g", x, y);double x = 27.5;doubley = 33.75;String s = String.format("x = %f y = %g", x, y);System.out.println(“String.format = “ + s);
Divisão por 0publicclass teste {publicstaticvoidmain(String[] args) {  try{    int x = 15;int z = 0;      double y = x / z;      System.out.println(“A divisão é “ + y);    }catch(ArithmeticException a){      System.out.println(“Erro!! Divisão por zero!!!”);    }  }}Ok. Isto lança uma ArithmeticException
Divisão por 0publicclass teste {publicstaticvoidmain(String[] args) {try{doublex = 15;double z = 0;doubley = x / z;      System.out.println(“A divisão é “ + x);    }catch(ArithmeticException a){  System.out.println(“Erro!! Divisão por zero!!!”);}}}WTF???????
Quer ver um dump da hierarquia de componentes numa aplicação Swing?Ctrl + Shift + F1Resultado no consoleBoa ferramenta para depuração! Swing
Qual o resultado disso?E isso?Brincando com URLsnew URL("http://www.guj.com.br").equals(new URL("http://208.109.100.149") )public intumMetodo(){System.out.println(“Acessando o Google:”);    http://www.google.com    return 1;}
Como acessar os métodos e campos privados de fora dessa classe?Arrebentando o encapsulamentopublicclassFoo {privateint bar;publicFoo() {setBar(17);}privatevoidsetBar(int bar) {this.bar=bar;}publicintgetBar() {return bar;}public String toString() {return "Foo[bar="+bar+"]";}}
Arrebentando o encapsulamentoimportjava.lang.reflect.*;publicclassArrebenta {publicstaticvoidmain(String[] args)throwsNoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException {Foofoo=newFoo();System.out.println(foo);Methodmethod=Foo.class.getDeclaredMethod       ("setBar", int.class);method.setAccessible(true);method.invoke(foo, 42);
Arrebentando o encapsulamento      System.out.println(foo);      Field field=Foo.class.getDeclaredField("bar");field.setAccessible(true);field.set(foo, 23);      System.out.println(foo);  }}Isso vai dar merda!
Acesso esquisitopublicclassFoo {staticintfubar = 42;FoogetFoo() {returnnull;        }publicstaticvoidmain(String args[]) {Foofoo = newFoo();        System.out.println(foo.getFoo().fubar);    }}// saida:  42Agora você tá de sacanagem!
É possível criar um programa sem Main!Classe sem main!publicclassWithoutMain {static {        System.out.println("Lookman, no main!!");        System.exit(0);    }}$ javaWithoutMainLookman, no main!!
Distribuída com o JDK  a partir da versão1.6_07Profiler leveIntegra uma série de ferramentas de linha de comandoVisualVMVeja mais:http://visualvm.java.net/
Todo arquivo .class começa com o valor hexadecimal 0xCAFEBABE, paraidentificá-lo como um arquivo de Bytecodeválido.Querexibiruma Splash screen?Bastarodar o programa com o parâmetro de máriona virtual splash:caminhoCuriosidadesjava -splash:imagem.jpeg -jar Reverso.jar
Classes anônimasVocê pode definir uma classe anônima e imediatamente chamar um método, mesmo que ela não implemente nenhuma interfacenewObject() {voidfoo(String s) {    System.out.println(s);  }}.foo("Hello");
Permite a criação de uma thread eu será chamada somente quando a JVM for encerradaGlobal JVM FinalizerLiberar recursosMatar programasFunciona com System.exit(), ou com CTRL-C / kill -15Obviamente, nãofunciona com kill -9, em *nixShutdown Hooks
Shutdown HooksRuntime.getRuntime().addShutdownHook(newThread() {publicvoidrun() {endApp(); }});;
Perguntas

Java hidden features

  • 1.
    Java HiddenFeaturesTraquitanas escondidas ou simplesmente pouco usadas no Java
  • 2.
    São “features” poucousadas do JavaNenhuma featureé escondida, apenas obscura, desconhecidaAlgumas delas são bem esquisitasMuitas consideradas até mesmo impossíveisUse com cautelaEm alguns casos, são facilidadesPorém, em outros, deixam as coisas mais complicadas.Podem piorar, por exemplo, a legibilidadeO que são HiddenFeatures
  • 3.
    Uma das formasmais estranhas de se criar um Map inicializado é através da Double BraceInitialization.Ex: Double BraceInitializationMapmap = newHashMap() {{ put("a key", "a value"); put("anotherkey", "anothervalue"); }}; Veja mais: http://www.c2.com/cgi/wiki?DoubleBraceInitialization
  • 4.
    WTF?Classes internas anônimasque herda de HashMapPortanto, herda métodos como put()Bloco de inicializaçãoChamado logo após a chamada a super()Em um construtor sem o “super”, passa a impressão de eu é chamado antes do construtorPode ser usado para agrupar lógica usada por vários construtoresÉ legal, mas evite!Double BraceInitialization
  • 5.
    Uma adição doJava 1.5 ainda pouco conhecida (ou percebida)Um método sobrescrito pode retornar uma subclasse da classe retornada pelo método da superclasse (ou interface)Necessário para o funcionamento de genericsCovariantReturnclass Super {Collection<String> values() { ... }}classSubClassextends Super { @OverrideList<String> values() { ... }}
  • 6.
    Quer lançar umaNullPointerException?Lançando NullPointerExcenptionpublicvoidmandaNullNaCara() {thrownull;}Como assim? O compilador pirou? Tá cobrando propina pra deixar isso passar?
  • 7.
    A instrução throw,ao ser processada, avalia a expressão à direita. Se a expressão gera um Throwable, este é lançadoEx: throwgetException()Se a expressão completa normalmente, produzindo um valor não nulo, retorna esse valorEx: thrownewSograEmCasaException()Se a expressão resulta em null, o null é convertido para NullpointerException!Lançando NullPointerExcenptionVeja mais: http://www.adarshr.com/papers/npe http://java.sun.com/docs/books/jls/
  • 8.
    Quer tirar umaexceção lançada de campo?Faz o return no finally!O código abaixo não lança a exceçãoBrincando com finallypublic static void fazAlgumaCoisa() { try { //Fazalgumacoisa… throw new RuntimeException(); } finally { return; } }
  • 9.
    Quem for pegofazendo isso vai sofrer vudu reverso!Um erro é para ser tratado ou lançado, nunca escondido!AtençãoVeja Mais: http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
  • 10.
    Como lançar umaexceção CHECADA de um método que não declara exceção!Agora mais bizarro ainda!importjava.rmi.RemoteException;classThrower {publicstaticvoidspit(final Throwable exception) {classEvilThrower<T extendsThrowable> { @SuppressWarnings("unchecked")privatevoidsneakyThrow(Throwable exception) throws T {throw (T) exception; } }newEvilThrower<RuntimeException>().sneakyThrow(exception); }}
  • 11.
    Agora mais bizarroainda!publicclassThrowerSample {publicstaticvoidmain( String[] args ) {Thrower.spit(newRemoteException("gounchecked!")); }}Mim não gostar de lançar exceção assim!
  • 12.
    Java não temgoto, mas...LabeledBlocksQuero ver isso funcionar!// codigosaifora:{ for (int i = 0; i < N; ++i) { for (int j = i; j < N; ++j) { for (int k = j; k < N; ++k) {//mais código pogbreaksaifora; } } }}
  • 13.
    LabeledBlockspublicstatic String getErrorMsg(String_data){    String _errMsg = “”;     VALIDATION:    {        if (_data.length() > 10)        {            _errMsg = “ERR: Data lengthexceed 10 chars”;            break VALIDATION;        }        // Resto docódigo de validação    }     // Tratamento da mensagem de erro    if (_errMsg.length() != 0)    {        _errMsg += “\nPleasefixtheerror.”;     }     return _errMsg;} Problem?
  • 14.
    Muita gente nãosabe, mas enums podem:Ter MétodosTer AtributosTer ConstrutoresImplementar interfacesEnumVeja mais:http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
  • 15.
    EnumenumCaes{MINOTAURO(2), TITAN(3), SADAM(7);privateintidade;Caes(intidade) {this.idade = idade; }publicintgetIdade() {returnidade;}}
  • 16.
    EnumpublicenumSalas implements Sala{PRIMEIRA{publicSalanorte() {returnSEGUNDA; } },SEGUNDA{publicSala sul() {returnPRIMEIRA; } }publicSala norte() { returnnull; }public Sala sul() { returnnull; }public Sala lest() { returnnull; }public Sala oeste() { returnnull; }}public interface Sala{public Sala norte();public Sala sul();public Sala leste();public Sala oeste();}
  • 17.
    Desde a versão1.5, o Java aceita parâmetros variáveisVar argspublicvoidfoo(String... bars) { for (String bar: bars) System.out.println(bar);}publicvoidtest() {foo("first","second","third")}
  • 18.
    Printf e String.formatPrintfdo entrou na versão 1.5String.format funciona analogamente, mas retorna ao invés de imprimirdouble x = 27.5;doubley = 33.75;System.out.printf("x = %f y = %g", x, y);double x = 27.5;doubley = 33.75;String s = String.format("x = %f y = %g", x, y);System.out.println(“String.format = “ + s);
  • 19.
    Divisão por 0publicclassteste {publicstaticvoidmain(String[] args) {  try{    int x = 15;int z = 0;      double y = x / z;      System.out.println(“A divisão é “ + y);    }catch(ArithmeticException a){     System.out.println(“Erro!! Divisão por zero!!!”);    }  }}Ok. Isto lança uma ArithmeticException
  • 20.
    Divisão por 0publicclassteste {publicstaticvoidmain(String[] args) {try{doublex = 15;double z = 0;doubley = x / z; System.out.println(“A divisão é “ + x); }catch(ArithmeticException a){ System.out.println(“Erro!! Divisão por zero!!!”);}}}WTF???????
  • 21.
    Quer ver umdump da hierarquia de componentes numa aplicação Swing?Ctrl + Shift + F1Resultado no consoleBoa ferramenta para depuração! Swing
  • 22.
    Qual o resultadodisso?E isso?Brincando com URLsnew URL("http://www.guj.com.br").equals(new URL("http://208.109.100.149") )public intumMetodo(){System.out.println(“Acessando o Google:”); http://www.google.com return 1;}
  • 23.
    Como acessar osmétodos e campos privados de fora dessa classe?Arrebentando o encapsulamentopublicclassFoo {privateint bar;publicFoo() {setBar(17);}privatevoidsetBar(int bar) {this.bar=bar;}publicintgetBar() {return bar;}public String toString() {return "Foo[bar="+bar+"]";}}
  • 24.
    Arrebentando o encapsulamentoimportjava.lang.reflect.*;publicclassArrebenta{publicstaticvoidmain(String[] args)throwsNoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException {Foofoo=newFoo();System.out.println(foo);Methodmethod=Foo.class.getDeclaredMethod ("setBar", int.class);method.setAccessible(true);method.invoke(foo, 42);
  • 25.
    Arrebentando o encapsulamento System.out.println(foo); Field field=Foo.class.getDeclaredField("bar");field.setAccessible(true);field.set(foo, 23); System.out.println(foo); }}Isso vai dar merda!
  • 26.
    Acesso esquisitopublicclassFoo {staticintfubar= 42;FoogetFoo() {returnnull; }publicstaticvoidmain(String args[]) {Foofoo = newFoo(); System.out.println(foo.getFoo().fubar); }}// saida: 42Agora você tá de sacanagem!
  • 27.
    É possível criarum programa sem Main!Classe sem main!publicclassWithoutMain {static { System.out.println("Lookman, no main!!"); System.exit(0); }}$ javaWithoutMainLookman, no main!!
  • 28.
    Distribuída com oJDK a partir da versão1.6_07Profiler leveIntegra uma série de ferramentas de linha de comandoVisualVMVeja mais:http://visualvm.java.net/
  • 29.
    Todo arquivo .classcomeça com o valor hexadecimal 0xCAFEBABE, paraidentificá-lo como um arquivo de Bytecodeválido.Querexibiruma Splash screen?Bastarodar o programa com o parâmetro de máriona virtual splash:caminhoCuriosidadesjava -splash:imagem.jpeg -jar Reverso.jar
  • 30.
    Classes anônimasVocê podedefinir uma classe anônima e imediatamente chamar um método, mesmo que ela não implemente nenhuma interfacenewObject() {voidfoo(String s) { System.out.println(s); }}.foo("Hello");
  • 31.
    Permite a criaçãode uma thread eu será chamada somente quando a JVM for encerradaGlobal JVM FinalizerLiberar recursosMatar programasFunciona com System.exit(), ou com CTRL-C / kill -15Obviamente, nãofunciona com kill -9, em *nixShutdown Hooks
  • 32.
  • 33.