JSR-311 at USP
I gave a talk about RESTful Web Services and JSR-311 at our local USPJUG meeting, the slides are available here (in portuguese).
I gave a talk about RESTful Web Services and JSR-311 at our local USPJUG meeting, the slides are available here (in portuguese).
Posted by
Rafael de F. Ferreira
at
7:06 PM
2
comments
This past week I've attended an event called Conexão Java. I've posted my notes on the other blog.
Posted by
Rafael de F. Ferreira
at
10:03 PM
1 comments
I'm trying to collect some idioms for programming with Java 5 generics, with varying degrees of usefulness, that I found scattered on different places. [Edit]Hopefully I fixed the whitespace problems on the code snippets. Blogger is pretty weak for working with source code, but now I believe its alright. As a bonus, I threw in another item on the end. I guess I'm all out of generic idioms for now.[/Edit]
public void compute(Runnable task)
interface Task extends Runnable, Serializable {}
public <T extends Runnable & Serializable> void compute(T task)
class Registry {
public void storeObject(Object obj) { }
public T getObject(Class<T> ofClass) {}
}
class Registry {
private Map<Class<?>, Object> objects = new HashMap<Class<?>, Object>();
public void storeObject(Object obj) {
objects.put(obj.getClass(), obj);
}
public <T> T getObject(Class<T> ofClass) {
Object instance = objects.get(ofClass);
return ofClass.cast(instance);
}
}
public interface ServiceLocator {
public Executor getExecutor();
}
class ServiceLocatorProps implements ServiceLocator {
private Executor executor;
public ServiceLocatorProps() throws Exception {
Properties props = new Properties();
props.load(getClass().getResourceAsStream("services.properties"));
String executorClassName = props.getProperty(
"java.util.concurrent.Executor");
Class<Executor> executorClass =
(Class<Executor>) Class.forName(executorClassName); //WARNING!!
this.executor = executorClass.newInstance();
}
public Executor getExecutor() {
return executor;
}
}
public ServiceLocatorProps() throws Exception {
Properties props = new Properties();
props.load(getClass().getResourceAsStream("services.properties"));
String executorClassName = props.getProperty(
"java.util.concurrent.Executor");
Class<?> loadedClass = Class.forName(executorClassName);
Class<? extends Executor> executorClass = loadedClass.asSubclass(Executor.class);
this.executor = executorClass.newInstance();
}
Posted by
Rafael de F. Ferreira
at
6:29 PM
0
comments
Há um tempinho eu postei aqui uma dica que deveria facilitar a construção de listas e maps em Java. A idéia básica era escrever uma classe utilitária com métodos estáticos usando varargs e genéricos que depois seriam importados (via static imports) nas classes clientes. Algo assim:
public class CollectionUtils {
public static List listWith(T... elements) {
return Arrays.asList(elements);
}
...
}
Isso até que funciona direto, mas não posso dizer o mesmo sobre a implementação do mapWith. Este método retorna um java.util.Map criado a partir de uma série de pares chave-valor. Cada par é representado por um objeto da classe Map.Entry<K,V> criado usando outro método estático. Assim um uso do mapWih poderia ser:
Map<NumeroNatural, String> numeros = mapWith(pair(ZERO, "0"), pair(ONE, "1"));
Para programar o mapWith eu usei o mesmo truque do listWith, receber os argumentos (os pares) via varargs:
public static <K, V> Map<K, V> mapWith(Map.Entry<K, V>... entries) {
HashMap<K, V> map = new HashMap<K, V>();
for (Map.Entry<K, V> eachEntry : entries)
map.put(eachEntry.getKey(), eachEntry.getValue());
return map;
}
Essa definição de método compila normalmente, mas todas as chamadas à ele receberão um warning do compilador avisando que um array genérico está sendo criado. "Huh? Mas eu não estou criando porcaria de array nenhum!", foi o que eu respondi para o compilador. Depois de me assegurar que ninguém me viu conversando com o javac.exe, que aliás é um interlocutor bem antipático, pesquisei um pouco e descobri que varargs no Java 5 usa arrays por baixo do pano. "Ok, mas qual é o problema de criar um array de tipo genérico?". Bom, vamos por partes, como diria o Leibniz. Primeiro precisamos lembrar que arrays são covariantes no tipo do seu elemento; veja:
String[] sa = new String[10];
Object[] oa = sa;
oa[0] = new Integer(5);
Class<String>[] ca = new Class<String>[10];
Object[] oa = ca;
ca[0] = new Integer(8);
Posted by
Rafael de F. Ferreira
at
2:14 AM
2
comments
[EDIT 22-09-2006: There is a bug on the mapWith code below. I explain what happened here.]
One of the things that bugs me about Java is that it lacks literal constructs for creating lists and maps*. This, coupled with the profusion of casts, can lead to APIs prefering arrays over collections, which are otherwise much easier to handle. Java 5 (Tiger) brought generics, helping to minimize all those annoying casts, but the verbosity for initializing collections is still an issue. Here is the result of a quick hack to try and improve things a bit:
public class Web2dot0 {
private List<String> buzzwords =
listWith("mashup", "AJAX", "bottom-up", "tagging");
private Map<Integer, String> strategy =
mapWith(pair(1, "Pretty AJAX UI"), pair(3, "profit!"));
...
}
public class CollectionUtils {
public static <E> List<E> listWith(E... items) {
return Arrays.asList(items);
}
public static <K, V> Map<K, V> mapWith(Map.Entry<K, V>... entries) {
HashMap<K, V> map = new HashMap<K, V>();
for (Map.Entry<K, V> eachEntry : entries)
map.put(eachEntry.getKey(), eachEntry.getValue());
return map;
}
public static <K, V> Map.Entry<K, V> pair(K key, V val) {
return new ImmutablePair<K, V>(key, val);
}
public static final class ImmutablePair<K, V> implements Map.Entry<K,V> {...}
...
}
Posted by
Rafael de F. Ferreira
at
2:00 AM
0
comments
Eu sou um pedestre convicto, pelo menos até eu mudar de idéia. Atravesso o campus da USP todo dia sobre as minhas duas pernas, cruzando as largas avenidas e as famosas rotatórias. Atravesso olhando para os dois lados, pois aparentemente esse layout viário é como um convite para os motoristas descarregarem suas frustrações no acelerador acertando, se tiverem sorte, um estudante ou dois no caminho.
Depois de muita enrolação, a prefeitura do campus resolveu o assunto instalando uma meia dúzia de semáfaros para o rebanho de alunos atravessar sem ser abatido. Eu deveria estar contentíssimo com o incremento na minha probabilidade de sobreviver à USP. Mas não. Eu odiei esses semáfaros. E não é porque eu tenho algum desejo inconsciente de comprar um carro veloz e sair atropelando polianos por aí.
Eu não gostei dos semáfaros porquê eles são, bem, feios. Não porquê poluem a paisagem ou outra viadagem desse tipo. São feios porque estragam um sistema que era belo. A beleza do trânsito organizado puramente pela combinação desses dois elementos, avenidas e rotatórias, é corrompida pelos sinais como se alguém escarrasse num Mondrian.
Voltando à vaca fria, admito que ainda não consegui uma resposta satisfatória sobre "o que é ciência da computação", mas tenho a impressão que a resposta envolve esse tipo de beleza. A criação de estruturas é uma constante na prática matemática moderna, mas o apreço ao minimalismo e à composibilidade me parecem marcas características da Ciência da Computação.
Um ótimo exemplo é a linguagem Lisp, onde todas as computações são funções e todo dado é uma lista. Outro exemplo é Smalltalk, onde tudo são objetos que se comunicam pela troca de mensagens. E como ficam as linguagens usadas por seres humanos normais? Retomando a analogia, Java parece um monte de semáfaros enfiados no pobre Smalltalk. E, embora eu nunca tenha programado em C++, ele me lembra um pouco o metrô de tokyo...
Posted by
Rafael de F. Ferreira
at
2:57 PM
0
comments