Vamos lá,
O operador ternário funciona da seguinte forma:
(<condição booleana>) ? <instruções caso seja verdadeiro> : <instruções caso seja falso falso>;
Até aqui tudo bem.
Nessa expressão, que você está passando, tem uma "pegadinha". Atribuição.
Em java uma condição booleana é qualquer expressão que retorne true ou false.
A variável c inicia com o valor falso.
A primeira "comparação" na verdade é uma atribuição (c= !c), note que não tem == e sim somente =, traduzindo: c = !false (negação de falso), que resulta em c = true.
Ao fazer c = !false (true) a variável c recebe o valor verdadeiro e retorna o valor para o IF, então ele vai para o segundo (c =!c) que fica c = !true, que resulta em c = false, a variável c recebe o valor falso e retorna para o IF, na segunda parte o false faz com que str receba o valor hello.
Resumindo:
Aqui temos uma atribuição (somente um =) e toda a atribuição o valor é retornado, nesse caso não dá erro pois a variável é do tipo booleano, se fosse de outro tipo resultaria em erro.
Note que o correto para comparação seria (==):
Se não fui claro, poste que tento melhorar ..rsrsr