Editar: The ticket I've linked in this answer ha sido marcado verificado/reparado. Se ha integrado en la última versión de Oxygen, as detailed in the release notes.Dejaré mi respuesta original a continuación, ya que contiene mucha información útil sobre cómo JDI y JDT trabajan juntos en Eclipse.
Voy a comenzar con la respuesta final a la pregunta por lo que no tiene que leer los detalles si usted no desea. Básicamente, esto es posible pero con muchas preguntas que deben ser respondidas primero. Si desea omitir eso e ir directamente al boleto, here you go, pero le recomiendo que siga leyendo.
Eclipse usa JDI (en la parte inferior de la página) para registrar los puntos de observación con la JVM. Esto se hace a través de los métodos EventRequestManager
(la implementación es proporcionada por la propia JVM, no por Eclipse) que crean puntos de observación, es decir, EventRequstManager.createModificationWatchpointRequest
. Lo único que aceptan estos métodos es un Field
(tenga en cuenta que esta no es la clase reflectante Field
). En resumen, Eclipse no puede hacerlo directamente a través de Java. No temas, Java tampoco maneja puntos de interrupción condicionales. Esos también se implementan a través de Eclipse directamente en lugar de depender de Java. Sin embargo, hay algunas advertencias que hacen que los puntos de observación condicionales sean mucho más difíciles de implementar que los puntos de interrupción condicionales.
Consideremos los puntos de interrupción condicionales y simples. Para que funcionen, necesitas un contexto en el que puedas ejecutar el fragmento de código. Sin un contexto de ejecución para el código, no podemos evaluar la expresión/declaraciones en el fragmento porque no tenemos forma de resolver variables, valores, tipos, etc. Esto se hace usando un analizador AST que procesa el código de Java en instrucciones reales . Recuerde que puede escribir un número de declaraciones en una condición, no solo una sola expresión. El evaluador luego utiliza un contexto (específicamente, un IJavaStackFrame
) para evaluar la expresión en sí misma después de analizarla.
Ahora piense en un punto de observación condicional, porque ese último punto es muy importante. ¿Cuál es el contexto de ejecución de un punto de observación? El acceso variable puede ocurrir no solo dentro de la misma clase, sino también en otras clases (piense en protected
y miembros del paquete), y también en clases internas (a través de MyClass.this.myField
). Esto significa que:
- las variables locales nunca son consistentes ya que el campo se puede acceder desde múltiples métodos,
- las variables miembro de la clase de la cual el acceso se invoca nunca son consistentes ya que el campo se puede acceder desde múltiples clases,
- las clases importadas que están disponibles en el contexto de ejecución no son consistentes para la misma razón que (2), y
- el acceso del campo en sí nunca es constante, ya que puede requerir cualificación con una instancia, nombre de clase,
super
o con algo así como MyClass.this.myField
(para acceso de clase interna).
La viabilidad de tal característica es algo limitada. Sería muy difícil evaluar realmente un enunciado condicional no cambiante para un punto de observación ya que absolutamente nada en el contexto de ejecución va a ser consistente. Esto significa que el código no puede ser fácilmente analiza y se interpreta sin significado especial aplicado a piezas del código, tales como:
myField
es siempre la misma como this.myField
o super.myField
o MyClass.myField
o MyClass.this.myField
, dependiendo de donde el campo es siendo accedido
Esto complica bastante las cosas, especialmente en un sistema que ya es relativamente complejo. Se puede encontrar un ejemplo del código de punto de interrupción condicional here (busque getEvaluationEngine
usando Ctrl + F). Ahora tome eso y agregue el procesamiento previo en la expresión en función de un conjunto de reglas sobre dónde estamos y dónde se encuentra el campo, y hacer las cosas puede ser complicado.
AFAIK, no puede hacer algo como "si el valor anterior/nuevo es esto, suspenda", porque esa información simplemente no está disponible en la información que puede obtener en el marco de pila (y por lo tanto depurador). La expresión que se asigna al valor se ha evaluado por el tiempo en que se golpea el punto de observación, pero su resultado no está disponible para el depurador, por lo tanto, no está disponible para un evaluador en el mismo punto de observación. Debería realizarse un paso primero para realizar la tarea, luego la expresión debería evaluarse después del paso. Sería horriblemente desordenado, y honestamente, bastante hacky en eso.
En cualquier caso, si desea expresar su apoyo a esta función, puede usar this Eclipse ticket. Sin embargo, ha existido desde 2005 (8 años a partir de ahora) y tiene un apoyo limitado de la comunidad. TBH, no veo que vaya muy lejos, especialmente sin una mayor clarificación de las expectativas detrás de este tipo de solicitud de funciones y sin una importante consideración de diseño puesta en primer lugar.
Lo que está buscando es algo así como [detector de cambios de propiedad] (http://docs.oracle.com/javase/tutorial/uiswing/events/propertychangelistener.html) que le permite detectar un cambio específico y captura el rastro de la pila No creo que esto esté disponible en ningún depurador aún, y será difícil de implementar si los desarrolladores originales de la biblioteca no lo convirtieron en una propiedad. – Cebence