AspectJ - 使用反射来实例化 not public class 的对象
AspectJ - Use reflection to instanciate object of not public class
我正在尝试在 AspectJ 中实例化一个非 public class 的对象。
我有这个class:
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() { /* (...) */ }
}
在class方面我希望能够做到:
Bill b = new Bill(currInvoice, idOperator, idClient);
问题是我得到一个错误:
The constructor Bill(int, String, String) is not visible
所以我调查并尝试使用反射,就像在 this post 中解释的那样。
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.
有谁知道是否有任何解决方法?
为什么要使用反射?
让我们假设 Bill
class 看起来像这样:
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:将 aspect 放入包中 ca1.business
构造函数是包私有的,即同一包中的其他 class 可以访问它。
package ca1.business;
public aspect MyAspect {
before() : execution(public static void main(String[])) {
Bill.instance = new Bill(11, "operator", "client");
}
}
选项 C:将工厂 class 作为助手放入受保护的包中
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]
我正在尝试在 AspectJ 中实例化一个非 public class 的对象。
我有这个class:
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() { /* (...) */ }
}
在class方面我希望能够做到:
Bill b = new Bill(currInvoice, idOperator, idClient);
问题是我得到一个错误:
The constructor Bill(int, String, String) is not visible
所以我调查并尝试使用反射,就像在 this post 中解释的那样。
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.
有谁知道是否有任何解决方法?
为什么要使用反射?
让我们假设 Bill
class 看起来像这样:
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:将 aspect 放入包中 ca1.business
构造函数是包私有的,即同一包中的其他 class 可以访问它。
package ca1.business;
public aspect MyAspect {
before() : execution(public static void main(String[])) {
Bill.instance = new Bill(11, "operator", "client");
}
}
选项 C:将工厂 class 作为助手放入受保护的包中
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]