2017-03-15 89 views
0

我想在AspectJ中实例化非公共类的对象。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. 

有谁知道是否有什么解决办法?

+0

请提供一个[mcve],其中包含**您的aspectj来源。 – GhostCat

+0

在类Bill中,你有一个包私有构造函数 - 它不能从另一个包中看到,因此将其公开并调用Bill b = new Bill(currInvoice,idOperator,idClient);没有反思。 – DontPanic

回答

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"); 
    } 
} 

宾得n 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]