问题1: 我有一个函数,这个函数没有参数,在函数中,我需要打印出  那个package 下的那个类 调用了 它。(注意:不要用throw exception,然后getStackTrace这个办法去获得类名。),  譬如:
calss A {method A : public static aaa(){ System.out.println("打印出:who call me..... ****") }}class b {
  public void bbb() {
     A.aaa();
  }}当b调用了a的时候a应该打印:.....b.bbb......
 
问题二:log4j 在每个类里都要初始化(读取配置文件,然后getLogger),我觉得麻烦就把他们分装在一个类里,public class log {
  
  static {
   ...........读却配置文件
  }  public static void debug() {
    ...打印debug信息。  }  public static void info() {
    ...打印infor信息。  }  public static void error() {
    ...打印error信息。  }........
}
其他类调用了我这个类打印信息没问题,在那个log的配置文件里的我写了
ConversionPattern=[%p] [%d] ******[%c]******* [MESSAGE] %m%n
请注意打星的地方,就是输出 完整的所在类的全名,
这时候打印的所有信息全部都是我的这个类的名称,当然我也知道:这就是这样。但是我想让他打印出调用这个类的类的名称。呵呵,这就和第一个问题有点象了。

解决方案 »

  1.   

    我不是什么高手,
     public static aaa()改为public static aaa(Object caller) caller为调用者不行吗?
    public static void debug(Object caller ) {
      if(caller!=null) System.out.println(caller.getClass());
      ...................... 
      }
      

  2.   

    1.
    实现了InvocationHandlen接口的任意类称为调用处理器,InvocationHandlen接口只有一个方法:
    Object invoke(Object proxy,Method method,Object [] args)
    只要调用了代理对象上的任意方法,invoke方法即会被调用,带着Method对象和原调用的参数,那么可以那么可以把A做为proxy
    ......................上面的不行,回家了...
      

  3.   

    class b {
      public void bbb() {
      System.out.println("俺是b");
         A.aaa();
      }}
      

  4.   

    Answer to Question 1:
    public static void xyz() {
        StackTraceElement x = new Throwable().getStackTrace()[1];
        System.out.println("Called by:"
           +x.getClassName()+"."+x.getMethodName()
           +" file: "+x.getFileName()+"("+x.getLineNumber()+")");
        ...
    }
      

  5.   

    在调用xyz()时,因为没有调用者的信息传入,唯一能得到调用者的信息的地方是堆栈,所以只能从堆栈中得到信息. 注意,堆栈中第一项是xyz()的信息,第二项才是调用者的信息.
    第二个问题可能用此法也可,没有用过log4j.
      

  6.   

    嗬嗬,谢谢各位,当然也要谢谢helpall() , 但是这里有个要求请注意******注意:不要用throw exception,然后getStackTrace这个办法去获得类名。**********大家继续讨论
      

  7.   

    第二个问题:
    Log4j有一个记录器层次问题。他会获得本类的记录器。如果没有再找他父类的记录器。  
    最后可能查继承根的记录器。
    我想你写在一个类里,他获得的只是这个类的信息。而和调用这个类的类无关。
      

  8.   

    To parol2910(树上的青蛙) 
    就因为他不想让我写成类,我才想写成类。不试过就不会知道。
    更确切的说法是:我就想把它写成类,不用每个地方初始化了。
      

  9.   

    在LOG4J中的读取配置文件又一个servlet不就可以实现吗。在需要调用的类里面可以
    private static Logger log = Logger.getLogger(UpdateServlet.class);
    生成一个静态变量不,这时候调用log.info之类的,但会自动记录所调用的类名。
    我在项目里面就是这样用的,不知道对不对。
      

  10.   

    设计的类要有一个参数Class.name  
    这样就可以了
      

  11.   

    变通一点的实现:class a{

    static void out(Object  p ){
    System.out.print(p.getClass().getName());
        
    }
    }

    class b{
    void  out(){
    a.out(this);
    }

    public static void main(String args[]){
    b bb=new b();
    bb.out();

    }
    }楼下继续
      

  12.   

    再变通一点:
    class a{

     void out( ){
    System.out.print(this.getClass().getName());
        
    }
    }

    class b extends a{
    public static void main(String args[]){
    b bb=new b();
    bb.out();

    }
    }不过失去了灵活性。
      

  13.   

    class a{

    static void out(){
     Runtime.getRuntime().traceMethodCalls(false);
     System.out.print(new Throwable().getStackTrace()[1].getClassName());    
    }
    }

    class b{
             void out(){
              a.out();
             }

    public static void main(String args[]){
    b bb=new b();
    bb.out();

    }
    }
      

  14.   

    System.out.println(sun.reflect.Reflection.getCallerClass(level));
    // level 是调用这类 离 这个方法的距离 1 是自己 , 2 是调用了自己所属类的那个类,以此类推。
      

  15.   

    // 补充一下,这样可能更明显。
    public  class OuterCaller {
      public static void main(String[] args){
         new OuterCaller().new InnerCaller().recordCallerClass();
      }  class InnerCaller{
         public void recordCallerClass(){
            int level = 1;
    Class caller = null;
    while ((caller = Reflection.getCallerClass(level)) != null) {
        System.out.println(caller);
                 level++;
    }
          }
       }
    }一次打印出 OuterCaller$InnerClass , OuterCaller.