【问题标题】:AspectJ - Use reflection to instanciate object of not public classAspectJ - 使用反射来实例化非公共类的对象
【发布时间】:2017-03-15 19:46:57
【问题描述】:

我正在尝试在 AspectJ 中实例化一个非公共类的对象。

我有这门课:

package ca1.business;

public class Bill {

    int id;
    String idOperator;
    String idClient;

    Bill(int id, String idOperator, String idClient) { /* (...) */ }
    public String toString() { /* (...) */ }
    public boolean equals(Object o) { /* (...) */ }
    public int getId() { /* (...) */ }
    public String getOperator() { /* (...) */ }
    public String getClient() { /* (...) */ }
}

在方面类中我希望能够做到:

Bill b = new Bill(currInvoice, idOperator, idClient);

问题是我得到一个错误:

The constructor Bill(int, String, String) is not visible

所以我调查并尝试使用反射,就像 this 帖子中解释的那样。

try {
    Constructor<Bill> cons = Bill.class.getDeclaredConstructor(null);
    cons.setAccessible(true);
    Bill invoice = cons.newInstance(null);
    invoice.id = 1;
    invoice.idOperator = "foo";
    invoice.idClient = "bar";
    // etc...
} catch (SecurityException e) {
    e.printStackTrace();
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}

但我在行中遇到错误:

invoice.id = 1;
invoice.idOperator = "foo";
invoice.idClient = "bar";

错误是:

The field Bill.X is not visible.

有谁知道有什么解决方法吗?

【问题讨论】:

  • 请提供一个minimal reproducible example,其中包含您的aspectj来源。
  • 在 Bill 类中,您有一个包私有构造函数 - 它在另一个包中不可见,因此将其公开并调用 Bill b = new Bill(currInvoice, idOperator, idClient);没有反射。

标签: java reflection aspectj


【解决方案1】:

为什么要使用反射?

让我们假设Bill 类如下所示:

package ca1.business;

public class Bill {
  int id;
  String idOperator;
  String idClient;

  Bill(int id, String idOperator, String idClient) {
    this.id = id;
    this.idOperator = idOperator;
    this.idClient = idClient;
  }

  @Override
  public String toString() {
    return "Bill [id=" + id + ", idOperator=" + idOperator + ", idClient=" + idClient + "]";
  }

  public static Bill instance;

  public static void main(String[] args) {
    System.out.println(instance);
  }
}

我们希望我们的方面在执行main 之前填充静态成员(愚蠢的示例,仅用于演示):

选项 A:特权方面

package de.scrum_master.aspect;

import ca1.business.Bill;

public privileged aspect MyAspect {
  before() : execution(public static void main(String[])) {
    Bill.instance = new Bill(11, "operator", "client");
  }
}

选项 B:将方面放入包 ca1.business

构造函数是包私有的,即同一个包中的其他类可以访问它。

package ca1.business;

public aspect MyAspect {
  before() : execution(public static void main(String[])) {
    Bill.instance = new Bill(11, "operator", "client");
  }
}

选项 C:将工厂类作为助手放入受保护的包中

package ca1.business;

public class BillFactory {
  public static Bill create(int id, String idOperator, String idClient) {
    return new Bill(id, idOperator, idClient);
  }
}
package de.scrum_master.aspect;

import ca1.business.Bill;
import ca1.business.BillFactory;;

public aspect MyAspect {
  before() : execution(public static void main(String[])) {
    Bill.instance = BillFactory.create(11, "operator", "client");
  }
}

每个选项 A、B、C 的控制台日志

Bill [id=11, idOperator=operator, idClient=client]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 2011-07-22
    相关资源
    最近更新 更多