Diogo Besson :: tecnologia

Brutal Diferença Java x PHP ( tipo / tipagem de variáveis / atributos )

Brutal Diferença Java x PHP ( tipo / tipagem de variáveis / atributos )

Brutal Diferença Java x PHP ( tipo / tipagem de variáveis / atributos ) mostra a diferença entre o Java e o PHP com relação à tipagem de variáveis. Confira abaixo!

Realizei ontem ( 29 / 04 ) um simuladinho do curso AJ1 da Globalcode pra testar os conhecimentos adquiridos e o aproveitamento do meu nível de atenção em relação a matéria fornecida durante as aulas, ou seja, pra ver se eu estava prestando atenção ou viajando na imaginação enquanto a aula corria.

A prova até que não estava impossível. De 12 questões, acertei 8. Muita gente caiu em pegadinhas e a paciência para ler o enunciado foi um diferencial relevante para o bom aproveitamento.

Pessoalmente, o que mais pegou foram os costumes de se programar diariamente em outra linguagem e realizar um teste com uma linguagem totalmente nova.

Eu queria introduzir aqui o conceito de tipagem, usando um exemplo dessa prova, como um ponto de brutal diferença entre o PHP e o Java.

A Questão foi mais ou menos essa:

O que acontece na tentativa de compilação e execução da seguinte classe? (1 alternativa)

(aqui entra a classe que imprime o resultado de um ternário para true( resultado 99.9 ) e false( resultado 9 ))

Respostas para false:

a) Imprime: “The value is 99.99”.
b) Imprime: “The value is 9”.
c) Imprime: “The value is 9.0”.
d) Erro.

A análise das possibilidades

Basicamente, quando uma linguagem de programação tem uma definição bem específica para os tipos de atributos dessa classe, dizemos que ela é uma linguagem de alta tipagem, ou, no jargão “fortemente tipada”.

Isso significa que ao declarar uma variável (leia-se também atributo de classe) devemos mostrar ao compilador, à JVM, ao apache, ao diabo ou a quem interessar possa, que a variavel é do tipo numérico (byte, short, inteiro, float, double), caracter, string de texto, string numérica, ou outros, a fim de que o valor que esta variável (ou objeto) recebe deva se enquadrar no tipo que a ela foi pré-definido.

No caso do PHP, vemos o funcionamento do scripting sem muita definição dos tipos das variáveis. Muitas inclusive são tratadas diretamente como arrays, o que para o Java seria um absurdo impensável e herege.

O ponto que o Java se diferencia do PHP no tratamento de variáveis é que a sua tipagem, além de ser forte, também hierarquiza os tipos de valores através da quantidade de bytes que eles ocupariam na memória.

Pode-se dizer que a JVM reserva na memória um espaço de acordo com o tipo, enquanto que o interpretador do PHP deixa um crescente em aberto para facilitar o desenvolvimento.

Citando Fluffycat: Um tipo byte ocupa 1 byte; Um tipo short ocupa 2 bytes; int ocupa 4 e long ocupa 8. No caso do Php, você desconhece o tipo, portanto o tamanho reservado na memória depende do que você vai inserir dentro dela.

Acontece que o tratamento hierárquico dado na solução das requisições Java pode gerar alguns problemas para os incautos.

Por exemplo… Se uma comparação com double e int, retorna double; Uma comparação de short com int, retorna int; Uma comparação de byte com float, retorna float ou double?

E assim começam os problemas…

Fiz os testes nas duas linguagens pra ver o que acontece

No Java, a coisa parece ser simples:

class TesteTernario {
public static void main (String [] args) {
int x = 4;
System.out.println( “The value is ” + ( (x>4) ? 99.9 : 9) );
}
}

Mas não é…

– Pegue o INTEIRO x que recebe 4;
– Compare o ternário booleano -> x>4 … o resultado será FALSE pois 4 é igual a 4 e nunca maior;
– O resultado para true seria o DOUBLE 99.9;
– O resultado para false seria o INT 9;
– Comparação de DOUBLE com INT retorna DOUBLE;
– O resultado do ternário é 9;
– Faça o cast automático para o tipo resultado double;
– Sua resposta será 9.0;
– Concatene-a com uma string e imprima na tela.

resultado:
c) Imprime: “The value is 9.0”.

Agora no PHP

class TesteTernario {
private $x = 4;

public function imprimeX() {
echo “The value is : “. ( ( ($this->x > 4) ? 99.9 : 9 ) );
}

public function __construct(){
return $this->imprimeX();
}

}

$teste = new TesteTernario();

– declare a classe que automaticamente executa seu construtor;
– resolva que private var x é igual ao numerico de valor 4;
– execute a função que imprime o valor de x dentro do ternário;
– resolva o ternário: numérico 4 é considerado igual ao literal 4, portando FALSE. Ignorando o valor true, iremos direto ao resultado de false, ou seja, literal 9;
– 9 torna-se uma string numérica, pois é concatenado a uma string que será impressa na tela.

resultado:
b) Imprime: “The value is 9”.

Resultados diferentes para um código que deveria fazer a mesma coisa. Isso é bom?

Eu digo que não.
Na minha opinião, o Java deveria ignorar o double e retornar diretamente o valor do tipo literal que ele foi declarado, no caso, int.

Acontece que se isso não fosse hierarquizado dessa maneira, outros problemas de resultado poderiam ocorrer. E outras comparações retornariam tipos incompatíveis.

No PHP não temos esse resultado, pois ele assume que string numérica é padrão de retorno para qualquer comparação, mas se a linguagem fosse fortemente tipada, um erro seria gerado. Inteiro é muito diferente de uma string numérica.

Enfim… Nesse quesito é difícil de afirmar qual seria o retorno ideal, por isso devemos ficar muito atentos às particularidades de cada linguagem para não perdermos de vista os retornos de certas expressões comparativas.

um abraço ao visitante.

Diogo Besson

.

7 Comments

  1. Rubens

    Diogo, tudo bom…
    Muito bom seu post, não tomou partido de nenhuma linguagem e demonstrou com exemplos. É difícil encontrar comparações desse tipo. Geralmente os programadores são Xiitas apaixonados pela sua plataforma.

    Eu concordo com seu post, mas não posso deixar de citar a falta que tipagem forte faz ao PHP. Apesar disso não impedir nem dificultar a programação, isso afeta a escalabilidade do sistema e, principalmente, a ‘adoção’ do código por outro programador.

    Onde trabalho, tentamos resolver isso através de uma forte documentação, onde os retornos de métodos e tipos de atributos são vigiados constantemente. Mas quando chega um novato na equipe é complicado explicar para eles por que não devem usar algo do tipo:
    if(!is_bool($valor)) throw…

    Quando o cara passa muito tempo trabalhando só com PHP acaba esquecendo a importância da assinatura dos métodos e tipo dos atributos. Então, se os códigos:
    if(true)

    e

    if(“passai parametro errado”)

    funcionam de qualquer forma, eles acabam esquecendo o risco em escala desse problema.

    Programo em PHP e C#, não gosto muito do Java, mas acho que a linguagem que mais respeita OO é Java. Espero pelo dia em que o PHP pelo menos nos dê a opção de forçar o tipo de um atritbuto ou retorno de um método.

    Abraço
    Rubens

  2. diogobesson

    Salve Rubens.

    Obrigado pela participação.

    Realmente o Java consegue ser o mais chato e o mais seguro nesse tipo de assunto.

    Devemos ter cuidado na comparação em qualquer linguagem que seja programada.

    Como seria esse resultado no c#?

    abraço!

    Dio

  3. claudio

    /*
    * Criado por SharpDevelop.
    * Usuário: claudio
    * Data: 4/8/2010
    * Hora: 18:08
    *
    * Para alterar este modelo use Ferramentas | Opções | Codificação | Editar Cabeçalhos Padrão.
    */
    using System;

    namespace testetern
    {
    class Program
    {
    public static void Main(string[] args)
    {
    int x = 4;
    Console.WriteLine(“this value is ” + ( (x>4) ? 99.9 : 9));

    // TODO: Implement Functionality Here

    Console.Write(“Press any key to continue . . . “);
    Console.ReadKey(true);
    }
    }
    }

    this value is 9

  4. diogobesson

    BOA, CLAUDIOOOO!!!! 😀 😀 😀

  5. Mauro

    Cara, no PHP existe uma coisa chamada indução de tipo. Por exemplo: em uma classe Foo existe um método Foo::bar(). Este médodo deve receber um objeto do tipo Bar (instância da classe Bar). Se você quer forçar o método Foo::bar() a receber o objeto do tipo Bar, basta declarar o método da seguinte maneira: Foo::bar(Bar $bar). Para admitir que $bar também possa ser do tipo NULL – lembrando que em PHP NULL é um tipo – então declare: Foo::bar(Bar $bar=null). Você poderia também testar: if($bar instanceof Bar){}. Existe uma extensão padrão do PHP chamada SPL que já define diversos tipos, inclusive estruturas de dados e exceções. Você também pode utilizar o Adapter Pattern para criar wrappers dos tipos primitivos, com o auxílio dos métodos mágicos. Através disso, é possível aumentar o nível de tipagem, trabalhando com os dois mundos: fracamente tipado (para apresentação e outros casos onde houver utilidade) e fortemente tipado para as camadas de dados e negócio, no caso de softwares de 3 camadas. Para mais informações, ler o manual do PHP.

  6. diogobesson

    bom…

    a inducao de tipos que vc comentou aqui (desculpe-me sobre os acentos. #lol) se chama type hinting (http://br.php.net/manual/en/language.oop5.typehinting.php) e esta disponivel – cheia de bugs – a partir do PHP 5.0 (lancado em julho de 2004) para Object e 5.1 (lancado em novembro de 2005) para Arrays.

    A ultima correcao de type hinting ate o momento foi o ticket #54624 lancado em agosto de 2011 (http://bugs.php.net/54624). Agora esta funcionando beeeeem melhor. #lol2

    o spl so ficou permanente a partir do PHP 5.3 (lancado em junho de 2009) (http://br.php.net/manual/en/spl.installation.php). Antes disso era uma tremenda gambi.

    como em abril de 2009 eu ainda trabalhava muito com PHP 4 e 5.0, acho que voce me deve um desconto, Maurao 🙂

    abracos e obrigado pelos comentarios! 😀 😀 😀

  7. Pingback: Top 5 « Diogo Besson :: web tecno log

Leave a Comment

O seu endereço de e-mail não será publicado.