<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-13102797</id><updated>2012-02-16T11:58:35.041-02:00</updated><category term='java'/><category term='generics'/><category term='comunidade'/><category term='spring'/><title type='text'>Java Pub</title><subtitle type='html'>Java, Design, Agilidade, Liberdade, Comunidade.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://javapub.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://javapub.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Tetsuo</name><uri>http://www.blogger.com/profile/10534840637169734177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/_CE05JKDR8zE/TEomHdZvqwI/AAAAAAAAVyc/GkPPgMYd1t8/S220/keitaro.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-13102797.post-4814017976457382141</id><published>2006-12-28T09:31:00.002-02:00</published><updated>2010-08-09T11:03:49.184-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><title type='text'>Generics + reflection + hierarquias de classes... argh!</title><content type='html'>Via &lt;a href="http://blog.urubatan.com.br/2006/12/27/dao-generico-um-exemplo-a-pedidos/#comment-1430"&gt;Urubatan&lt;/a&gt;, li este &lt;a href="http://blog.caelum.com.br/2006/10/29/brincando-com-generics-o-bizarregenericdao/"&gt;post no blog Caelum&lt;/a&gt; que mostra um exemplo (como dito no próprio post, bizarro) de um DAO genérico, com resolução 'automática' do tipo da classe persistente via reflection do parâmetro de tipo.&lt;br /&gt;&lt;br /&gt;Numa API que eu estava projetando, eu tentei usar este tipo de truque, para evitar ter que passar a classe de parametro no construtor, mas isso quebra rapidinho, quando entram hierarquias de classes. Exemplo:&lt;br /&gt;&lt;pre&gt;public class Dao&lt;t&gt; {&lt;br /&gt;private Class&lt;t&gt; persistentClass;&lt;br /&gt;public Dao() {&lt;br /&gt;   this.persistentClass = (Class&lt;t&gt;)((ParameterizedType)getClass()&lt;br /&gt;       .getGenericSuperclass()).getActualTypeArguments()[0];&lt;br /&gt;}&lt;br /&gt;public void save(T object) {&lt;br /&gt;   System.out.println("Saving object of class " + persistentClass);&lt;br /&gt;}&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;   Dao&lt;date&gt; dao = new Dao&lt;date&gt;(){};&lt;br /&gt;   dao.save(new Date());&lt;br /&gt;}&lt;br /&gt;}&lt;t extends="" serializable=""&gt;&lt;t&gt;&lt;t&gt;&lt;date&gt;&lt;date&gt;&lt;/date&gt;&lt;/date&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/date&gt;&lt;/date&gt;&lt;/t&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;Beleza, isso funciona (imprime o tipo correto). Mas, como eu quero adicionar métodos ao DAO, eu crio uma subclasse:&lt;br /&gt;&lt;pre&gt;public class PessoaDao extends Dao&lt;pessoa&gt; {&lt;br /&gt;// ...&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;   PessoaDao dao = new PessoaDao();&lt;br /&gt;   dao.save(new Pessoa());&lt;br /&gt;}&lt;br /&gt;}&lt;pessoa&gt;&lt;/pessoa&gt;&lt;/pessoa&gt;&lt;/pre&gt;Isso continua funcionando. Mas, com o decorrer do projeto, eu preciso criar uma subclasse mais especializada:&lt;br /&gt;&lt;pre&gt;public class PessoaJuridicaDao extends PessoaDao {&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;   PessoaJuridicaDao dao = new PessoaJuridicaDao();&lt;br /&gt;   dao.save(new PessoaJuridica());&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;... e isto quebra o esquema (&lt;span style="font-family:courier new;"&gt;ClassCastException&lt;/span&gt;), pois não há mais parâmetro de tipo na superclasse. Eu poderia deixar isto funcionando se mantivesse o parametro de tipo no &lt;span style="font-family:courier new;"&gt;PessoaDao&lt;/span&gt;:&lt;br /&gt;&lt;pre&gt;public class PessoaDao&lt;t&gt; extends Dao&lt;t&gt; {&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;   PessoaDao&lt;pessoa&gt; dao = new PessoaDao&lt;pessoa&gt;();&lt;br /&gt;   dao.save(new Pessoa());&lt;br /&gt;}&lt;br /&gt;}&lt;t extends="" pessoa=""&gt;&lt;t&gt;&lt;pessoa&gt;&lt;pessoa&gt;&lt;/pessoa&gt;&lt;/pessoa&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pessoa&gt;&lt;/pessoa&gt;&lt;/t&gt;&lt;/t&gt;&lt;/pre&gt;... mas daí eu ia ter que, ou modificar todas as declarações de &lt;span style="font-family:courier new;"&gt;PessoaDao&lt;/span&gt; para &lt;span style="font-family:courier new;"&gt;PessoaDao&lt;pessoa&gt;&lt;/pessoa&gt;&lt;/span&gt;, ou então ter que conviver com milhares de warnings.&lt;br /&gt;&lt;br /&gt;Outro problema é se uma subclasse faz algo deste tipo:&lt;br /&gt;&lt;pre&gt;public class PessoaDao&lt;doc&gt; extends Dao&lt;pessoa&gt; {&lt;br /&gt;public Pessoa load(DOC chave) { return new Pessoa(); } //dummy&lt;br /&gt;}&lt;doc extends="" tipodocumento=""&gt;&lt;pessoa&gt;&lt;/pessoa&gt;&lt;/doc&gt;&lt;/pessoa&gt;&lt;/doc&gt;&lt;/pre&gt;&lt;pre&gt;public class PessoaJuridicaDao extends PessoaDao&lt;tipocnpj&gt; {&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;   PessoaJuridicaDao dao = new PessoaJuridicaDao();&lt;br /&gt;   dao.save(new PessoaJuridica());&lt;br /&gt;}&lt;br /&gt;}&lt;tipocnpj&gt;&lt;/tipocnpj&gt;&lt;/tipocnpj&gt;&lt;/pre&gt;Isto imprime "&lt;span style="font-family:courier new;"&gt;Saving object of class class &lt;/span&gt;&lt;b style="font-family: courier new;"&gt;TipoCnpj&lt;/b&gt;"!&lt;br /&gt;&lt;br /&gt;O caso é, este é um mecanismo extremamente frágil. Creio que até seria possível recuperar o parâmetro &lt;span style="font-family:courier new;"&gt;&lt;pessoa&gt;&lt;/pessoa&gt;&lt;/span&gt;, se percorrêssemos a hierarquia, mas será que vale a pena entrar nesse terreno arcano?&lt;br /&gt;&lt;br /&gt;Ter que passar uma classe como parâmetro do construtor agora não parece tão ruim assim. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13102797-4814017976457382141?l=javapub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blog.caelum.com.br/2006/10/29/brincando-com-generics-o-bizarregenericdao/' title='Generics + reflection + hierarquias de classes... argh!'/><link rel='replies' type='application/atom+xml' href='http://javapub.blogspot.com/feeds/4814017976457382141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13102797&amp;postID=4814017976457382141' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default/4814017976457382141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default/4814017976457382141'/><link rel='alternate' type='text/html' href='http://javapub.blogspot.com/2006/12/generics-reflection-hierarquias-de.html' title='Generics + reflection + hierarquias de classes... argh!'/><author><name>Tetsuo</name><uri>http://www.blogger.com/profile/10534840637169734177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/_CE05JKDR8zE/TEomHdZvqwI/AAAAAAAAVyc/GkPPgMYd1t8/S220/keitaro.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13102797.post-112481194999881733</id><published>2005-08-23T12:42:00.001-03:00</published><updated>2010-08-09T11:03:34.939-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><title type='text'>Simplicidade e produtividade no acesso a banco, com Spring</title><content type='html'>&lt;p&gt;Exemplo de uma consulta com atualização de banco de dados, usando JDBC puro, Spring+JDBC e Spring+Hibernate:&lt;/p&gt;&lt;span style="font-weight: bold;"&gt;JDBC:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;public void nomeUpperCase(long id) {&lt;br /&gt;Connection con = null;&lt;br /&gt;PreparedStatement ps1 = null;&lt;br /&gt;PreparedStatement ps2 = null;&lt;br /&gt;ResultSet rs = null;&lt;br /&gt;try {&lt;br /&gt; con = dataSource.getConnection();&lt;br /&gt; con.setAutoCommit(false);&lt;br /&gt; ps1 = con.prepareStatement(&lt;br /&gt;    "update NOME from CLIENTES where ID = ?");&lt;br /&gt; ps1.setLong(1, id);&lt;br /&gt; ResultSet rs = ps1.executeQuery();&lt;br /&gt; if (rs.next()) {&lt;br /&gt;    String nome = rs.getString("NOME");&lt;br /&gt;    ps2 = con.prepareStatement("update CLIENTES set NOME = ? where ID = ?");&lt;br /&gt;    ps2.setString(1, nome.trim().toUpperCase());&lt;br /&gt;    ps2.setLong(2, id);&lt;br /&gt;    ps2.executeUpdate();&lt;br /&gt; }&lt;br /&gt; con.commit();&lt;br /&gt;} catch (SQLException e) {&lt;br /&gt; con.rollback();&lt;br /&gt;} finally {&lt;br /&gt; if (rs != null) {&lt;br /&gt;    try {&lt;br /&gt;       rs.close();&lt;br /&gt;    } catch (SQLException e1) {&lt;br /&gt;       e.printStackTrace();&lt;br /&gt;    }&lt;br /&gt; }&lt;br /&gt; if (ps2 != null) {&lt;br /&gt;    try {&lt;br /&gt;       ps2.close();&lt;br /&gt;    } catch (SQLException e1) {&lt;br /&gt;       e.printStackTrace();&lt;br /&gt;    }&lt;br /&gt; }&lt;br /&gt; if (ps1 != null) {&lt;br /&gt;    try {&lt;br /&gt;       ps1.close();&lt;br /&gt;    } catch (SQLException e1) {&lt;br /&gt;       e.printStackTrace();&lt;br /&gt;    }&lt;br /&gt; }&lt;br /&gt; if (con != null) {&lt;br /&gt;    try {&lt;br /&gt;       con.close();&lt;br /&gt;    } catch (SQLException e1) {&lt;br /&gt;       e.printStackTrace();&lt;br /&gt;    }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Spring+JDBC:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;public void nomeUpperCase(long id) {&lt;br /&gt;String nome = (String) getJdbcTemplate().queryForObject(&lt;br /&gt; "select NOME from CLIENTES where ID = ?",&lt;br /&gt; new Object[] { new Long(id) },&lt;br /&gt; new RowMapper() {&lt;br /&gt;    public Object mapRow(ResultSet rs) {&lt;br /&gt;       return rs.getString("NOME");&lt;br /&gt;    }&lt;br /&gt; });&lt;br /&gt;getJdbcTemplate().update(&lt;br /&gt; "update CLIENTES set NOME = ? where ID = ?",&lt;br /&gt; new Object[] { nome.trim().toUpperCase(), new Long(id) });&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Spring+Hibernate:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;public void nomeUpperCase(long id) {&lt;br /&gt;Cliente c = (Cliente) getHibernateTemplate().load(Cliente.class, new Long(id));&lt;br /&gt;c.setNome(c.getNome().trim().toUpperCase());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Preciso dizer mais alguma coisa? :)&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13102797-112481194999881733?l=javapub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javapub.blogspot.com/feeds/112481194999881733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13102797&amp;postID=112481194999881733' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default/112481194999881733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default/112481194999881733'/><link rel='alternate' type='text/html' href='http://javapub.blogspot.com/2005/08/simplicidade-e-produtividade-no-acesso.html' title='Simplicidade e produtividade no acesso a banco, com Spring'/><author><name>Tetsuo</name><uri>http://www.blogger.com/profile/10534840637169734177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/_CE05JKDR8zE/TEomHdZvqwI/AAAAAAAAVyc/GkPPgMYd1t8/S220/keitaro.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13102797.post-112481144092637844</id><published>2005-08-22T12:30:00.001-03:00</published><updated>2010-08-09T11:04:11.215-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><title type='text'>Spring ao resgate!</title><content type='html'>Segundo seu criador, o objetivo do Spring é facilitar a criação de aplicações J2EE, reduzindo o esforço e o custo de desenvolvimento, e ao mesmo tempo melhorando a cobertura de testes e a qualidade.&lt;br /&gt;&lt;br /&gt;Na prática, ele preenche uma lacuna, a da camada de negócio.&lt;br /&gt;&lt;br /&gt;No início, era o MVC. Pioneiro, o Struts criou uma base para a implementação da apresentação da aplicação, incluindo controle de navegação, validação e reúso de fragmentos (Tiles). Mais tarde, vários outros frameworks para a camada de apresentação foram criados, alguns que seguiram a linha do Struts, implementando o padrão MVC, outros tentando novos modelos, como o Tapestry e o JSF, que utilizam uma abstração de componentes e eventos.&lt;br /&gt;&lt;br /&gt;Depois, foi a vez da camada de persistência. Mapeadores O/R como o Hibernate, o OJB e o iBatis surgiram para facilitar o uso do banco de dados, oferecendo um modelo mais orientado a objetos, mesmo sobre um banco de dados relacional, além de promover a portabilidade entre bancos de dados.&lt;br /&gt;&lt;br /&gt;Entre as camadas de apresentação e de persistência, fica a camada de negócio, ou de aplicação. É lá que a dita lógica de negócio se concentra, fazendo a ligação entre o armazenamento e a visualização/manipulação dos dados. E é nessa camada que a lógica específica da aplicação, isto é, que é mais ligada intimamente ao domínio do negócio, e não à tecnologia da implementação, se localiza.&lt;br /&gt;&lt;br /&gt;Os outros frameworks (apresentação e persistência) resolvem problemas tecnológicos, respectivamente as limitações e complexidades das APIs Servlet e JDBC. Mas como é possível simplificar a implementação de uma camada que é constituída basicamente de lógica específica, que não pode ser generalizada e automatizada facilmente por um framework?&lt;br /&gt;&lt;br /&gt;Bem, não é bem assim. A camada de negócio, tradicionalmente, fica longe de conter apenas lógica de negócio. Isso porque ela ainda tem que lidar com diferentes APIs, incluindo as dos frameworks de apresentação e de persistência, além de ser necessário algum tipo de gerenciamento e organização das classes. Assim, o código de negócio normalmente fica enterrado em um emaranhado de blocos try/catch/finally, para lidar com SQLExceptions, HibernateExceptions, etc. Além disso, muitas vezes os desenvolvedores se vêem na necessidade de abusar de alguns padrões de projeto, como o Abstract Factory e o Singleton. Deste modo, mais da metade do código da camada de negócio acabava lidando com aspectos tecnológicos, e não com regras negócio.&lt;br /&gt;&lt;br /&gt;Os Enterprise JavaBeans (EJB) foram originalmente criados para fazer parte desta camada, e especificavam um modelo de componentes, com formas de acesso a recursos, controle transacional, remotabilidade e gerenciamento de ciclo de vida. Porém, a complexidade necessária para fornecer estas funcionalidades era alta, além de forçar um forte acoplamento ao container EJB com suas APIs invasivas.&lt;br /&gt;&lt;br /&gt;O Spring surgiu para simplificar este cenário. Ele foi projetado para ser modular e o menos invasivo possível, e ao mesmo tempo flexível e poderoso. O framework foi construído sobre o conceito da Inversão de Controle (Inversion of Control, ou IoC), fazendo uso extenso de um container de injeção de dependências (Dependency Injection, ou DI), um framework simplificado de AOP, e de classes auxiliares que ajudam na integração com outros frameworks, encapsulando detalhes da tecnologia e fornecendo hooks de customização via callbacks.&lt;br /&gt;&lt;br /&gt;Bom, o parágrafo anterior contém vários jargões, que tento explicar a seguir:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Inversão de Controle: Também chamado de "Princípio de Hollywood", isto é, "Don't call us, we call you". Esta é uma característica comum aos frameworks, que implementam o fluxo principal de parte do sistema, fornecendo pontos de extensão para o desenvolvedor de aplicação adicionar a lógica específica. Assim, não é a aplicação que 'chama' o framework (como funcionam as bibliotecas), mas sim o framework que 'chama' os módulos da aplicação.&lt;/li&gt;    &lt;li&gt;Injeção de Dependências: Definido por Martin Fowler, este padrão descreve um modo de gerência de componentes e resolução de dependências onde as dependências dos componentes (recursos como DataSources, configurações e outros componentes) são 'injetadas' pelo container na inicialização do componente, se contrapondo ao tradicional Service Locator, onde o componente pede um recurso ao locator. Esta inversão faz com que toda a configuração seja feita no container, retirando a necessidade da criação de fábricas customizadas. Isto facilita a execução de testes (pode-se usar objetos de teste diretamente, ao invés de ter que se criar uma fábrica de objetos de teste) e promove o desacoplamento entre os componentes.&lt;/li&gt;   &lt;li&gt;Callbacks: Interfaces que encapsulam uma determinada parte de um algoritmo, chamadas pela implementação concreta do algoritmo. Um exemplo no Spring seria a execução de uma query SQL: Normalmente, você teria que obter uma conexão com o banco, criaria um PreparedStatement, informaria os parâmetros, executaria a consulta, transformaria os dados do ResultSet em algum objeto ou lista, trataria as exceções e liberaria os recursos. Os 'templates' do Spring implementam toda a lógica, exceto a leitura e transformação do ResultSet. Apenas este trecho do algoritmo é implementado pelo desenvolvedor da aplicação, na forma de um callback, sem se preocupar com a execução da consulta e a liberação de recursos.&lt;/li&gt;   &lt;li&gt;AOP: A programação orientada a aspectos é um outro pardigma de programação, complementar à orientação a objetos, que visa modularizar aspectos que permeiam os limites entre objetos, como gerenciamento de recursos, logging, controle de transações, etc. O Spring fornece uma biblioteca de 'componentes AOP', que simplificam o desenvolvimento, controlando coisas como conexões com o banco e transações de maneira centralizada e totalmente transparente às classes de negócio.&lt;/li&gt; &lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13102797-112481144092637844?l=javapub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javapub.blogspot.com/feeds/112481144092637844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13102797&amp;postID=112481144092637844' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default/112481144092637844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default/112481144092637844'/><link rel='alternate' type='text/html' href='http://javapub.blogspot.com/2005/08/spring-ao-resgate.html' title='Spring ao resgate!'/><author><name>Tetsuo</name><uri>http://www.blogger.com/profile/10534840637169734177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/_CE05JKDR8zE/TEomHdZvqwI/AAAAAAAAVyc/GkPPgMYd1t8/S220/keitaro.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13102797.post-111734535529509892</id><published>2005-05-29T02:34:00.001-03:00</published><updated>2010-08-09T11:04:20.222-03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='comunidade'/><title type='text'>Por que Java?</title><content type='html'>&lt;span class="postbody"  style="font-family:arial;"&gt;Bem, este texto eu escrevi em resposta a um post no &lt;a href="http://www.javafree.com.br/forum/index.php"&gt;JavaFree&lt;/a&gt; de um rapaz que acabou de entrar no curso de Ciência da Computação, sobre a escolha entre Java e C#. Como eu gostei do produto final (e &lt;/span&gt;&lt;span class="postbody"  style="font-family:arial;"&gt;gastei um bom tempo &lt;/span&gt;&lt;span class="postbody"  style="font-family:arial;"&gt;escrevendo isso), vou postar aqui, mesmo sem ter feito uma nota de abertura do blog ainda... -sigh--&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span class="postbody"&gt; Se você souber bem como projetar um sistema, tanto faz a linguagem. Um bom desenvolvedor Java pode aprender a sintaxe e as bibliotecas necessárias do C# em dois meses (já que ele é uma cópia escarrada mesmo). Claro que a produtividade só vem com o tempo e com a prática (leva tempo pra decorar a documentação das classes, né), mas nada que não se resolva com algum estudo e esforço (disso você não vao conseguir correr, não importa a linguagem). Idem pra um desenvolvedor C#.&lt;br /&gt;&lt;br /&gt;O detalhe, que na minha opinião faz toda a diferença, é que no mundo Java há a cultura da &lt;span style="font-weight: bold;"&gt;liberdade&lt;/span&gt;, da &lt;span style="font-weight: bold;"&gt;qualidade&lt;/span&gt;, do &lt;span style="font-weight: bold;"&gt;aprendizado&lt;/span&gt; e do &lt;span style="font-weight: bold;"&gt;compartilhamento de conhecimento&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Por mais que o pessoal da FSF &lt;a href="http://www.gnu.org/philosophy/java-trap.html" target="_blank" class="postlink"&gt;reclame&lt;/a&gt;, a Sun mantém o Java de forma &lt;a href="http://www.jcp.org/" target="_blank" class="postlink"&gt;extremamente aberta&lt;/a&gt;, dando &lt;a href="https://mustang.dev.java.net/" target="_blank" class="postlink"&gt;poder aos usuários e desenvolvedores&lt;/a&gt;, ao invés de manipular a evolução dele &lt;a href="http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish" target="_blank" class="postlink"&gt;unicamente a seu favor&lt;/a&gt;. Tem também a liberdade de escolha, já que o Java roda em &lt;a href="http://www.apple.com/macosx/" target="_blank" class="postlink"&gt;qualquer SO&lt;/a&gt; &lt;a href="http://fedora.redhat.com/" target="_blank" class="postlink"&gt;que possua uma JVM&lt;/a&gt;. Há &lt;a href="http://geronimo.apache.org/" target="_blank" class="postlink"&gt;servidores de aplicação&lt;/a&gt; e &lt;a href="http://www.netbeans.org/" target="_blank" class="postlink"&gt;IDEs&lt;/a&gt; &lt;a href="http://www.gnu.org/philosophy/free-sw.html" target="_blank" class="postlink"&gt;livres&lt;/a&gt;, e a JVM é &lt;a href="http://java.sun.com/j2se/1.5.0/download.jsp" target="_blank" class="postlink"&gt;gratuita&lt;/a&gt; (a versão livre &lt;a href="http://osdir.com/Article5408.phtml" target="_blank" class="postlink"&gt;já está a caminho&lt;/a&gt;), o que possibilita o uso da plataforma a custo zero (e sem pirataria!), tanto para aprendizado, desenvolvimento e produção. Os &lt;a href="http://struts.apache.org/" target="_blank" class="postlink"&gt;frameworks&lt;/a&gt; mais usados têm o código aberto. As arquiteturas e a forma de implementação deles não é segredo pra ninguém, pelo contrário, são discutidos de forma &lt;a href="http://struts.apache.org/mail.html" target="_blank" class="postlink"&gt;livre e aberta&lt;/a&gt;, geralmente com o incentivo de seus desenvolvedores. Pode-se usar isso como ferramenta de aprendizado, pois todo o código está aí, para entendermos e aprendermos. Também há toneladas de &lt;a href="http://java.sun.com/reference/index.html" target="_blank" class="postlink"&gt;documentação&lt;/a&gt;, &lt;a href="http://www.javafree.com.br/forum/index.php?c=4" target="_blank" class="postlink"&gt;tutoriais&lt;/a&gt; e &lt;a href="http://www.javaalmanac.com/" target="_blank" class="postlink"&gt;exemplos&lt;/a&gt; na Internet, é só &lt;a href="http://www.google.com/" target="_blank" class="postlink"&gt;saber procurar&lt;/a&gt;, fora, é claro, a imensa base de conhecimento acumulado em fóruns como o do &lt;a href="http://www.javafree.com.br/forum/index.php" target="_blank" class="postlink"&gt;JavaFree&lt;/a&gt;, &lt;a href="http://www.guj.com.br/" target="_blank" class="postlink"&gt;GUJ&lt;/a&gt;,&lt;a href="http://www.java.net/" target="_blank" class="postlink"&gt; Java.net&lt;/a&gt;, &lt;a href="http://www.theserverside.com/" target="_blank" class="postlink"&gt;TheServerSide&lt;/a&gt;, dos &lt;a href="http://forum.springframework.org/" target="_blank" class="postlink"&gt;próprios projetos open-source&lt;/a&gt;, etc.&lt;br /&gt;&lt;br /&gt;Além disso, normalmente desenvolvedores Java consideram coisas do tipo 'SQL em JSP' um lixo, e somos encorajados a projetar a aplicação de forma bem estruturada. &lt;a href="http://www.corej2eepatterns.com/index.htm" target="_blank" class="postlink"&gt;Patterns&lt;/a&gt; e &lt;a href="http://www.hibernate.org/" target="_blank" class="postlink"&gt;frameworks&lt;/a&gt; fazem parte do dia-a-dia do desenvolvedor java, agregando valor e melhorando a qualidade do software (bem, muitas vezes as pessoas exageram, o que é mau, mas fazer o que...)&lt;br /&gt;&lt;br /&gt;Também há o fator 'comunidade'. Existem &lt;a href="http://community.java.net/jugs/listing.csp" target="_blank" class="postlink"&gt;dezenas de comunidades Java&lt;/a&gt;, &lt;a href="http://www.javafree.com.br/forum/index.php?c=5" target="_blank" class="postlink"&gt;regionais&lt;/a&gt;, &lt;a href="http://soujava.org.br/jsp/index.jsp" target="_blank" class="postlink"&gt;nacionais&lt;/a&gt; e &lt;a href="http://www.guj.com.br/user.index.chain" target="_blank" class="postlink"&gt;virtuais&lt;/a&gt; (como o &lt;a href="http://www.javafree.com.br/" target="_blank" class="postlink"&gt;nosso JavaFree&lt;/a&gt;!). Elas unem os desenvolvedores, ajudando-os a evoluir como profissionais.&lt;br /&gt;&lt;br /&gt;Bem, não conheço o &lt;a href="http://www.microsoft.com/" target="_blank" class="postlink"&gt;mundo Microsoft&lt;/a&gt;, nunca programei uma única linha de C# ou de ASP, então não posso dizer muita coisa sobre &lt;a href="http://msdn.microsoft.com/" target="_blank" class="postlink"&gt;'o outro lado'&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;O que posso dizer é que não me arrependo de estar aqui, pois o Java me possibilitou adquirir conhecimentos que eu tenho certeza que jamais iria adquirir sendo programador C# (os cursos são caros demais!). E se algum dia eu tiver que aprender C#, eu compro um livro e depois de uns dois ou três meses, sei que terei condições de aplicar todos os conhecimentos adquiridos aqui, de forma muito mais efetiva que a maioria dos programadores ASP por aí.&lt;br /&gt;&lt;br /&gt;Mas por enquanto, concentre-se em Estruturas de Dados e Análise de Algoritmos, e veja se sai daí desse curso sabendo alguma coisa além de uma linguagem X ou Y.&lt;br /&gt;&lt;br /&gt;Tetsuo&lt;/span&gt; &lt;/blockquote&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13102797-111734535529509892?l=javapub.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.javafree.com.br/forum/viewtopic.php?p=85590#85590' title='Por que Java?'/><link rel='replies' type='application/atom+xml' href='http://javapub.blogspot.com/feeds/111734535529509892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13102797&amp;postID=111734535529509892' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default/111734535529509892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13102797/posts/default/111734535529509892'/><link rel='alternate' type='text/html' href='http://javapub.blogspot.com/2005/05/por-que-java.html' title='Por que Java?'/><author><name>Tetsuo</name><uri>http://www.blogger.com/profile/10534840637169734177</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/_CE05JKDR8zE/TEomHdZvqwI/AAAAAAAAVyc/GkPPgMYd1t8/S220/keitaro.jpg'/></author><thr:total>8</thr:total></entry></feed>
