¿Por qué solemos usar `||` no `|`, ¿cuál es la diferencia?

Solo me pregunto por qué solemos usar OR lógico || entre dos booleanos no bit a bit O | , aunque ambos funcionan bien.

Quiero decir, mira lo siguiente:

 if(true | true) // pass if(true | false) // pass if(false | true) // pass if(false | false) // no pass 
 if(true || true) // pass if(true || false) // pass if(false || true) // pass if(false || false) // no pass 

Podemos usar | en lugar de || ? Lo mismo con & y && .

Si usas el || y && formas, en lugar de | y & formas de estos operadores, Java no se molestará en evaluar solo el operando de la mano derecha.

Se trata de si desea provocar un cortocircuito en la evaluación o no, la mayoría del tiempo que desee.

Una buena forma de ilustrar los beneficios del cortocircuito sería considerar el siguiente ejemplo.

 Boolean b = true; if(b || foo.timeConsumingCall()) { //we entered without calling timeConsumingCall() } 

Otro beneficio, como mencionaron Jeremy y Peter, para los cortocircuitos es el cheque de referencia nulo:

 if(string != null && string.isEmpty()) { //we check for string being null before calling isEmpty() } 

más información

| no realiza la evaluación de cortocircuito en expresiones booleanas. || dejará de evaluar si el primer operando es verdadero, pero | no lo hará

Además, | se puede usar para realizar la operación O bit a bit en los valores byte / short / int / long. || no poder.

Entonces, para construir sobre las otras respuestas con un ejemplo, el cortocircuito es crucial en los siguientes controles defensivos:

 if (foo == null || foo.isClosed()) { return; } if (bar != null && bar.isBlue()) { foo.doSomething(); } 

Usando | y, en su lugar, podría dar lugar a que se NullPointerException una NullPointerException aquí.

Lógica || y & consulte el lado derecho solo si es necesario. El | y compruebe ambos todo el tiempo.

Por ejemplo:

 int i = 12; if (i == 10 & i < 9) // It will check if i == 10 and if i < 9 ... 

Reescribirlo:

 int i = 12; if (i == 10 && i < 9) // It will check if i == 10 and stop checking afterward because i doesn't = 10 ... 

Otro ejemplo:

 int i = 12; if (i == 12 | i > 10) // It will check if i == 12 and it will check if i > 10 ... 

Reescribirlo:

 int i = 12; if (i == 12 || i > 10) // It will check if i == 12, it does, so it stops checking and executes what is in the if statement ... 

También note una trampa común: los operadores no perezosos tienen preferencia sobre los perezosos, entonces:

 boolean a, b, c; a || b && c; //resolves to a || (b && c) a | b && c; //resolves to (a | b) && c 

Tenga cuidado al mezclarlos.

Además del cortocircuito, otra cosa a tener en cuenta es que realizar una operación lógica bit a bit en valores que pueden ser distintos de 0 o 1 tiene un significado muy diferente al de la lógica condicional. Mientras que USUALMENTE es el mismo para | y || , con & y && obtiene resultados muy diferentes (por ejemplo, 2 & 4 es 0 / falso, mientras que 2 && 4 es 1 / verdadero).

Si lo que obtienes de una función es en realidad un código de error y estás probando el no-cero, esto puede importar bastante.

Esto no es un problema tan grande en Java donde tienes que encasillar explícitamente a boolean o comparar con 0 o similar, pero en otros lenguajes con syntax similar (C / C ++ et al) puede ser bastante confuso.

Además, tenga en cuenta que & y | solo se puede aplicar a valores de tipo entero, y no a todo lo que puede ser equivalente a una prueba booleana. De nuevo, en lenguajes que no son Java, hay bastantes cosas que se pueden usar como booleano con una comparación implícita de != 0 (punteros, flotantes, objetos con un operator bool() , etc.) y los operadores bit a bit son casi siempre sin sentido en esos contextos.

La única vez que usarías | o & lugar de || o && es cuando tienes expresiones booleanas muy simples y el costo del corte corto (es decir, una twig) es mayor que el tiempo que guardas al no evaluar las expresiones posteriores.

Sin embargo, esta es una micro-optimización que rara vez importa, excepto en el código de nivel más bajo.

|| es el operador lógico u operador mientras | es el operador bit a bit

 boolean a = true; boolean b = false; if (a || b) { } int a = 0x0001; a = a | 0x0002; 

Además del hecho de que | es un operador bit a bit: || es un operador de cortocircuito: cuando un elemento es falso, no verifica los demás.

  if(something || someotherthing) if(something | someotherthing) 

si algo es VERDADERO, || no evaluará a alguien más, mientras | va a hacer Si las variables en tus sentencias if son en realidad llamadas a funciones, usando || posiblemente esté ahorrando mucho rendimiento.

a | b: evaluar b en cualquier caso

a || b: evalúa b solo si se evalúa como falso

 | is the binary or operator || is the logic or operator 

Los operadores || y && se llaman operadores condicionales , mientras | y se llaman operadores bit a bit . Ellos sirven diferentes propósitos.

Los operadores condicionales solo funcionan con expresiones que evalúan estáticamente a boolean en los lados izquierdo y derecho.

Los operadores bit a bit trabajan con cualquier operando numérico.

Si desea realizar una comparación lógica, debe usar operadores condicionales , ya que agregará algún tipo de seguridad de tipo a su código.

Una nota al margen: Java tiene | = pero no es un || =

Un ejemplo de cuándo debes usar || es cuando la primera expresión es una prueba para ver si la segunda expresión explotaría. por ejemplo, utilizando un solo | en el siguiente caso podría resultar en un NPE.

 public static boolean isNotSet(String text) { return text == null || text.length() == 0; } 

|| devuelve un valor booleano al poner en OR dos valores (es por eso que se lo conoce como LOGICAL o)

ES DECIR:

 if (A || B) 

Devolvería verdadero si A o B es verdadero, o falso si ambos son falsos.

| es un operador que realiza una operación bit a bit en dos valores. Para entender mejor las operaciones bit a bit, puedes leer aquí:

http://en.wikipedia.org/wiki/Bitwise_operation

Una diferencia principal es que || y && exhibir “cortocircuito”, por lo que el RHS solo se evaluará si es necesario.

Por ej.

 if (a || b) { path1... } else { path2.. } 

Arriba si a es verdadero, entonces b no se probará y se ejecutará la ruta 1. Si | fue utilizado, ambos lados serían evaluados incluso si ‘a’ es verdadero.

Vea Aquí y aquí , para obtener un poco más de información.

Espero que esto ayude.

No cortocircuito puede ser útil. A veces quieres asegurarte de que dos expresiones evalúen. Por ejemplo, supongamos que tiene un método que elimina un objeto de dos listas separadas. Es posible que desee hacer algo como esto:

 class foo { ArrayList list1 = new ArrayList(); ArrayList list2 = new ArrayList(); //Returns true if bar is removed from both lists, otherwise false. boolean removeBar(Bar bar) { return (list1.remove(bar) & list2.remove(bar)); } } 

Si su método en su lugar usó el operando condicional, no podría eliminar el objeto de la segunda lista si la primera lista devolvió falso.

 //Fails to execute the second remove if the first returns false. boolean removeBar(Bar bar) { return (list1.remove(bar) && list2.remove(bar)); } 

No es increíblemente útil, y (como con la mayoría de las tareas de progtwigción) puede lograrlo con otros medios. Pero es un caso de uso para operandos bit a bit.

Las otras respuestas han hecho un buen trabajo al cubrir la diferencia funcional entre los operadores, pero las respuestas podrían aplicarse a casi todos los lenguajes derivados de C que existen en la actualidad. La pregunta está etiquetada con java , por lo que intentaré responder específica y técnicamente para el lenguaje Java.

& y | puede ser Operadores de bits enteros u Operadores lógicos booleanos. La syntax para los operadores lógicos y bit a bit ( §15.22 ) es:

 AndExpression: EqualityExpression AndExpression & EqualityExpression ExclusiveOrExpression: AndExpression ExclusiveOrExpression ^ AndExpression InclusiveOrExpression: ExclusiveOrExpression InclusiveOrExpression | ExclusiveOrExpression 

La syntax para EqualityExpression se define en §15.21 , que requiere RelationalExpression definida en §15.20 , que a su vez requiere ShiftExpression y ReferenceType definidos en §15.19 y §4.3 , respectivamente. ShiftExpression requiere AdditiveExpression definido en §15.18 , que continúa profundizando, definiendo la aritmética básica, operadores unarios, etc. ReferenceType profundiza en todas las formas de representar un tipo. (Aunque ReferenceType no incluye los tipos primitivos, la definición de tipos primitivos es en última instancia necesaria, ya que pueden ser del tipo de dimensión para una matriz, que es un ReferenceType ).

Los operadores bitwise y lógicos tienen las siguientes propiedades:

  • Estos operadores tienen diferente precedencia, con & tienen la mayor precedencia y | la precedencia más baja.
  • Cada uno de estos operadores es sintácticamente asociativo a la izquierda (cada grupo de izquierda a derecha).
  • Cada operador es conmutativo si las expresiones del operando no tienen efectos secundarios.
  • Cada operador es asociativo.
  • Los operadores lógicos y de bit se pueden usar para comparar dos operandos de tipo numérico o dos operandos de tipo boolean . Todos los demás casos dan como resultado un error en tiempo de comstackción.

La distinción entre si el operador sirve como operador bit a bit o como operador lógico depende de si los operandos son “convertibles a un tipo integral primitivo” ( §4.2 ) o si son de tipo boolean o Boolean ( §5.1.8 ).

Si los operandos son tipos integrales, la promoción numérica binaria ( §5.6.2 ) se realiza en ambos operandos, dejándolos tanto como long s como int s para la operación. El tipo de operación será el tipo de operandos (promocionados). En ese punto, & será bit a bit AND, ^ será a nivel de bit exclusivo O, y | será bit a bit inclusive ( §15.22.1 )

Si los operandos son boolean o Boolean , los operandos estarán sujetos a la conversión de unboxing si es necesario ( §5.1.8 ), y el tipo de operación será boolean . & dará como resultado true si ambos operandos son true , ^ dará como resultado true si ambos operandos son diferentes, y | dará como resultado true si cualquiera de los operandos es true . ( §15.22.2 )

Por el contrario, && es el “operador condicional” ( §15.23 ) y || es el “operador condicional” ( §15.24 ). Su syntax se define como:

 ConditionalAndExpression: InclusiveOrExpression ConditionalAndExpression && InclusiveOrExpression ConditionalOrExpression: ConditionalAndExpression ConditionalOrExpression || ConditionalAndExpression 

&& es como & , excepto que solo evalúa el operando correcto si el operando de la izquierda es true . || es como | , excepto que solo evalúa el operando correcto si el operando izquierdo es false .

Conditional-Y tiene las siguientes propiedades:

  • El operador condicional-syntactically se asocia a la izquierda (se agrupa de izquierda a derecha).
  • El operador condicional y es totalmente asociativo con respecto a los efectos secundarios y el valor del resultado. Es decir, para cualquier expresión a , b , y c , la evaluación de la expresión ((a) && (b)) && (c) produce el mismo resultado, con los mismos efectos secundarios que ocurren en el mismo orden, como la evaluación del expresión (a) && ((b) && (c)) .
  • Cada operando del operador condicional y debe ser de tipo boolean o Boolean , o se produce un error en tiempo de comstackción.
  • El tipo de expresión condicional es siempre boolean .
  • En tiempo de ejecución, la expresión del operando de la izquierda se evalúa primero; si el resultado tiene un tipo Boolean , está sujeto a la conversión de unboxing ( §5.1.8 ).
  • Si el valor resultante es false , el valor de la expresión condicional y es false y la expresión del operando de la derecha no se evalúa.
  • Si el valor del operando de la izquierda es true , entonces se evalúa la expresión de la mano derecha; si el resultado tiene un tipo Boolean , está sujeto a la conversión de unboxing ( §5.1.8 ). El valor resultante se convierte en el valor de la expresión condicional.
  • Por lo tanto, && calcula el mismo resultado que & en operandos boolean . Solo difiere en que la expresión del operando de la derecha se evalúa condicionalmente en lugar de siempre.

Conditional-O tiene las siguientes propiedades:

  • El operador condicional u operador es sintácticamente de asociación izquierda (se agrupa de izquierda a derecha).
  • El operador condicional u operador es totalmente asociativo con respecto a los efectos secundarios y el valor del resultado. Es decir, para cualquier expresión a , b , y c , evaluación de la expresión ((a) || (b)) || (c) ((a) || (b)) || (c) produce el mismo resultado, con los mismos efectos secundarios que ocurren en el mismo orden, como la evaluación de la expresión (a) || ((b) || (c)) (a) || ((b) || (c)) .
  • Cada operando del operador condicional u operador debe ser de tipo boolean o Boolean , o se produce un error en tiempo de comstackción.
  • El tipo de expresión condicional es siempre boolean .
  • En tiempo de ejecución, la expresión del operando de la izquierda se evalúa primero; si el resultado tiene un tipo Boolean , está sujeto a la conversión de unboxing ( §5.1.8 ).
  • Si el valor resultante es true , el valor de la expresión condicional es true y la expresión del operando de la derecha no se evalúa.
  • Si el valor del operando de la izquierda es false , entonces se evalúa la expresión de la mano derecha; si el resultado tiene un tipo Boolean , está sujeto a la conversión de unboxing ( §5.1.8 ). El valor resultante se convierte en el valor de la expresión condicional.
  • Por lo tanto, || calcula el mismo resultado que | en operandos boolean o Boolean . Solo difiere en que la expresión del operando de la derecha se evalúa condicionalmente en lugar de siempre.

En resumen, como @JohnMeagher ha señalado repetidamente en los comentarios, & y | son, de hecho, operadores booleanos que no son de cortocircuito en el caso específico de que los operandos sean boolean o Boolean . Con buenas prácticas (es decir, sin efectos secundarios), esta es una diferencia menor. Sin embargo, cuando los operandos no son boolean o Boolean , los operadores se comportan de manera muy diferente: en modo bit y las operaciones lógicas simplemente no se comparan bien con el alto nivel de progtwigción de Java.

La diferencia básica entre ellos es que | primero convierte los valores a binarios y luego realiza el bit o la operación. Mientras tanto, || no convierte los datos en binarios y solo ejecuta la expresión o en su estado original.

 int two = -2; int four = -4; result = two | four; // bitwise OR example System.out.println(Integer.toBinaryString(two)); System.out.println(Integer.toBinaryString(four)); System.out.println(Integer.toBinaryString(result)); Output: 11111111111111111111111111111110 11111111111111111111111111111100 11111111111111111111111111111110 

Leer más: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk

1). (Expresión1 | expresión2), | el operador evaluará expression2 independientemente de si el resultado de expression1 es verdadero o falso.

Ejemplo:

 class Or { public static void main(String[] args) { boolean b=true; if (b | test()); } static boolean test() { System.out.println("No short circuit!"); return false; } } 

2). (Expresión1 || expresión2), || el operador no evaluará expression2 si expression1 es verdadero.

Ejemplo:

 class Or { public static void main(String[] args) { boolean b=true; if (b || test()) { System.out.println("short circuit!"); } } static boolean test() { System.out.println("No short circuit!"); return false; } } 

| = en bit o, || = lógica o

usualmente uso cuando hay un incremento previo y un operador de incremento de post. Mira el siguiente código:

 package ocjpPractice; /** * @author tithik * */ public class Ex1 { public static void main(String[] args) { int i=10; int j=9; int x=10; int y=9; if(i==10 | ++i>j){ System.out.println("it will print in first if"); System.out.println("i is: "+i); } if(x==10 ||++x>y){ System.out.println("it will print in second if"); System.out.println("x is: "+x); } } } 

salida:

se imprimirá primero si
yo soy: 11

se imprimirá en el segundo si
x es: 10

ambos if bloques son iguales pero el resultado es diferente. cuando hay | , ambas condiciones serán evaluadas. Pero si es || , no evaluará la segunda condición ya que la primera condición ya es verdadera.

Hay muchos casos de uso que sugieren por qué debería elegir || en lugar de | . Algunos casos de uso tienen que usar | operador para verificar todas las condiciones.

Por ejemplo, si desea verificar la validación del formulario y desea mostrar al usuario todos los campos no válidos con textos de error en lugar de solo un primer campo no válido.

|| operador sería,

  if(checkIfEmpty(nameField) || checkIfEmpty(phoneField) || checkIfEmpty(emailField)) { // invalid form with one or more empty fields } private boolean checkIfEmpty(Widget field) { if(field.isEmpty()) { field.setErrorMessage("Should not be empty!"); return true; } return false; } 

Por lo tanto, con el fragmento de arriba, si el usuario envía el formulario con TODOS los campos vacíos, SÓLO se mostrará el campo de nombre con mensaje de error. Pero, si lo cambias a,

  if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) { // invalid form with one or more empty fields } 

Mostrará un mensaje de error apropiado en cada campo, independientemente de true condiciones true .

Cuando tuve esta pregunta, creé el código de prueba para tener una idea al respecto.

 public class HelloWorld{ public static boolean bool(){ System.out.println("Bool"); return true; } public static void main(String []args){ boolean a = true; boolean b = false; if(a||bool()) { System.out.println("If condition executed"); } else{ System.out.println("Else condition executed"); } } } 

En este caso, solo cambiamos el valor del lado izquierdo de si la condición agrega a o b.

|| Escenario, cuando el lado izquierdo es verdadero [if (a || bool ())]

salida "If condition executed"

|| Escenario, cuando el lado izquierdo es falso [if (b || bool ())]

Salida-

 Bool If condition executed 

Conclusion of || Cuando uso || , el lado derecho solo marca cuando el lado izquierdo es falso.

| Escenario, cuando el lado izquierdo es verdadero [if (a | bool ())]

Salida-

 Bool If condition executed 

| Escenario, cuando el lado izquierdo es falso [if (b | bool ())]

Salida-

 Bool If condition executed 

Conclusion of | Cuando uso | , verifique ambos lados izquierdo y derecho.

|| es un o lógico | es un poco sabio o.

Operadores de Java

| es bit a bit o, || es lógico o.

Echa un vistazo a:

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html

| es a nivel de bit inclusive O

|| es lógico O

| es un operador bit a bit || es un operador lógico

Uno tomará dos bits y / o ellos.

Uno determinará la verdad (esto O eso) Si esto es cierto o si es verdadero, entonces la respuesta es verdadera.

Ah, y las personas responden estas preguntas rápidamente.