论坛首页 Java企业应用论坛

是谁调用了它的静态方法?

浏览 9252 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-12-14  
我该如何知道是哪个子类调用了它的静态方法?有必要吗?

//ActiveRecord.java
public abstract class ActiveRecord {

    public static int count() {
        //我应该如何知道,Xxx.count()中的Xxx实际是什么类?
        //假如java在此可以使用关键字class,用以表示实际调用该静态方法的类:
        Class targetClass = class;
        String hql = "select count(*) from " + targetClass.getSimpleName() 
              + " where " + propertyName + "=?";
        List list = theStaticHibernateTemplate.find(hql, value);
        return (Integer) list.get(0);
    }

}


//Entity.java

@MappedSuperclass
public abstract class Entity extends ActiveRecord {
...
}

//User.java
@Entity
public User extends Entity {...}

//Topic.java
@Entity
public Topic extends Entity {...}



//XxxAction.java
public void someMethod(){
    //ActiveRecord.count中的targetClass 将是User.class
    int userCount = User.count(); 

    //ActiveRecord.count中的targetClass 将是Topic.class
    int topicCount = Topic.count(); 
}


我如何完成如上的做法?
   发表时间:2007-12-14  
为什么不设计成:

public void someMethod(){  
        int userCount = ActiveRecord .count(User.class);   
        int topicCount = ActiveRecord .count(Topic.class);   

public class ActiveRecord
{
public static int count(Class clazz)
{
....
}
}
或者 SPING里面 HibernateSupport类 和HibernateTemplate...(大概是这个名字)那样设计?

对你的代码:在static method 里面得到执行这个方法的引用,好象不可以:
首先应该明确一点: static method是被称为类方法,它的意义是这个类所有对象共同的方法,这个方法被调用,就相当于:这个类所有的对象一起调用这个方法一次,既然是一起调用,你又怎么知道到底是谁调用了这个方法呢。
所以根据语法,static不能用 this,super关键字,这就是你无法在ActiveRecord中得到targetClass对象的原因。

个人见解,敬请指正。
0 请登录后投票
   发表时间:2007-12-14  
好像javaeye以前贴过:

//参数0:返回sun.reflect.Reflection
//参数1:返回本类
//参数2以上,依次返回方法调用栈上的类
Class targetClass = Reflection.getCallerClass(2); 

还有另外一种方法也是一样:
String caller = new Throwable().getStackTrace()[2].getClassName();
0 请登录后投票
   发表时间:2007-12-14  
LS的方法无法做到,试验如下:

//ActiveRecord.java
package net.paoding.ar.test;

import sun.reflect.Reflection;

public abstract class ActiveRecord {
    public static int count() {
        System.out.println("Reflection.getCallerClass(1)=" + Reflection.getCallerClass(1));
        System.out.println("Reflection.getCallerClass(2)=" + Reflection.getCallerClass(2));
        System.out.println("Reflection.getCallerClass(3)=" + Reflection.getCallerClass(3));
        System.out.println("Reflection.getCallerClass(4)=" + Reflection.getCallerClass(4));
        return 3;
    }
}


//User.java
public class User extends ActiveRecord {

}



//UserAction.java
public class UserAction {
    public static void main(String[] args) {
        User.count();
    }
}


打印结果:
Reflection.getCallerClass(0)=class sun.reflect.Reflection
Reflection.getCallerClass(1)=class net.paoding.ar.test.ActiveRecord
Reflection.getCallerClass(2)=class net.paoding.ar.test.UserAction
Reflection.getCallerClass(3)=null
Reflection.getCallerClass(4)=null


==〉通过Reflection.getCallerClass无法嘚知程序使用的是User.count()而非ActiveRecord.count()



我反编译了UserAction.class,确定.class文件中仍然保持User.count()的叙述,
这意味着,虚拟机完全可以提供API来让编程者获得。

到底是否有这样的API? 这个特性如果无法从语言本身得到满足,将是很难过。
0 请登录后投票
   发表时间:2007-12-14  
啊。。我看错了。

方法栈的确不包含子类的信息。
0 请登录后投票
   发表时间:2007-12-14  
应该是编译期的信息无法在运行期使用
User.count()前加User只是为了编译的目的,真正到了运行期这个信息就被丢弃了,再说,如果不丢弃,这个信息可以放在哪里呢?放在count方法上?还是放在User类声明上?好像都不可以。
0 请登录后投票
   发表时间:2007-12-14  
如果要放,则是放在栈上

简单地,可认为java的每个method是栈上的一个元素,jvm完全可以把当前谁"."的这个method放入栈的这个元素中。

在instance方法中,这个"谁"由 this 扮演,现在缺少的是用某个关键字来扮演static method的这个"谁"

我触及了这个问题,真是很不幸
0 请登录后投票
   发表时间:2007-12-14  
我昨天也触及了一个有点类似的问题,比如一个模板类
class ABC<E>{
public void someMethod(){
}
}

我想在someMethod里知道E到底是什么类,想了很久,好像也是无解
0 请登录后投票
   发表时间:2007-12-14  
velna_007 写道
我昨天也触及了一个有点类似的问题,比如一个模板类
class ABC<E>{
public void someMethod(){
}
}

我想在someMethod里知道E到底是什么类,想了很久,好像也是无解

这个有解

给你参考:http://www.hibernate.org/328.html


public abstract class GenericHibernateDAO<T, ID extends Serializable>
        implements GenericDAO<T, ID> {

    private Class<T> persistentClass;
    private Session session;

    public GenericHibernateDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
                                .getGenericSuperclass()).getActualTypeArguments()[0];
     }
}
0 请登录后投票
   发表时间:2007-12-14  
不知道你有没有试过,这个行不通。。。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics