当前位置:编程学习 > JAVA >>

怎么得到java类下引用的所有的类?

如这个类:
import java.util.*;
import java.lang.String;
public class Info {
    Date date = null;
    java.sql.Date sqlDate = new java.sql.Date(date.getTime());
    public List<String> getTimes(Integer in,String s){
        date = new Date();
        List<String> as = new ArrayList<String>();
        as.add("s");
        as.add("1"); 
        return as;
    }
}
我怎么得到所引用的类是:
java.util.Date,
java.util.List,
java,util.ArrayList,
java.lang.String,
java.lang.Integer;
我使用的是eclipse ast, 可以得到但是不对,比如:
得到字段申明:
1,Date date = null;    //这个我只能得到类型为Date,而且不是java.util.Date,因此我无法知道,这            个Date是java.util.Date,还是java.sql.Date;
java.sql.Date sqlDate = new java.sql.Date(date.getTime());   //这个得到的类型就是直接是:java.sql.Date;
问题:请问这个应该怎么确定?
2,还有返回类型:public List<String> getTimes(Integer in,String s)。这个返回是List<String>,我这怎么确实这个带有泛型的类型?

3,还有关于注解的类型,不过注解我想一定要先引入包吧。

4,如果我在代中用到没有申明的类,应该怎么得到呢?如:
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis()); 
或者:
cal.setTimeInMillis(new Long(2134531215L));
这两种直接使用的应该怎么来得到? java eclipse ast eclipse ase --------------------编程问答-------------------- 反射技术http://blog.sina.com.cn/s/blog_3c62c21f01011xci.html --------------------编程问答-------------------- 反射拿不方法里面的类型申明。 --------------------编程问答--------------------
引用 2 楼 tuxming 的回复:
反射拿不方法里面的类型申明。


反射后你用getGenericReturnType取返回值类型看看,别用getReturnType --------------------编程问答-------------------- 1, Java在编译的时候,Date是什么类型,会把Full-name,编译到.class中,
写成 Date只是给程序写着和看着方便的,换句话,你不可能不知道它的具体类型是什么。

2. 没太明白你关心什么,但是反射是可以得知一个类型是否是 泛型类的。

3. 肯定要引入了。

4.  --------------------编程问答--------------------
引用 4 楼 healer_kx 的回复:
1, Java在编译的时候,Date是什么类型,会把Full-name,编译到.class中,
写成 Date只是给程序写着和看着方便的,换句话,你不可能不知道它的具体类型是什么。

2. 没太明白你关心什么,但是反射是可以得知一个类型是否是 泛型类的。

3. 肯定要引入了。

4.




引用 3 楼 silenceburn 的回复:
引用 2 楼 tuxming 的回复:反射拿不方法里面的类型申明。

反射后你用getGenericReturnType取返回值类型看看,别用getReturnType


我就是要得到一个java文件所有引用的类的full-name(就是带包的类名),最终于得到的是一个java文件里面的所有  引用到的类的full-name: Collection<String> 

以上的情况就是会在代码中出现的,针对每一种情况,具体我不知道怎么弄,
反射,好像是得不方法体里面的代码所引用的类,情况4就是指的方法体里面的代码段,

最明显的问题就是:我在java文件的开头,import java.util.*;
我在一个方法体中使用了,Set set = new HashSet();这个是正确的,但是我怎么得到一个java.util.Set这个类型呢? 因为在头文件中引用的是*,而不是Set,根据import得不到java.util.Set这个字符串。

--------------------编程问答--------------------
引用 5 楼 tuxming 的回复:
引用 4 楼 healer_kx 的回复:1, Java在编译的时候,Date是什么类型,会把Full-name,编译到.class中,
写成 Date只是给程序写着和看着方便的,换句话,你不可能不知道它的具体类型是什么。

2. 没太明白你关心什么,但是反射是可以得知一个类型是否是 泛型类的。

3. 肯定要引入了。

4.



引用 3 楼 s……


总算大概明白你的困惑在那里了。生成CLASS字节码的时候JVM把类型都确定完了,字节码里没import。
你反射也反射不出来import是怎么写的的。

你要的东西就是 
System.out.println(Info.class.getClasses());
所有引用到的类都会返回,具体可以看getClasses()的注释:

--------------------编程问答-------------------- import时包名 java.util已确定,下面程序中类名Set又已确定,就能唯一确定the qualified name: java.util.Set --------------------编程问答--------------------
引用 6 楼 silenceburn 的回复:
引用 5 楼 tuxming 的回复:引用 4 楼 healer_kx 的回复:1, Java在编译的时候,Date是什么类型,会把Full-name,编译到.class中,
写成 Date只是给程序写着和看着方便的,换句话,你不可能不知道它的具体类型是什么。

2. 没太明白你关心什么,但是反射是可以得知一个类型是否是 泛型类的。

3. 肯定要引入了。

……


按照你说的:

Class<?>[] cs = Info.class.getClasses();
System.out.println(cs.length);

输出是:0 --------------------编程问答--------------------
引用 7 楼 dracularking 的回复:
import时包名 java.util已确定,下面程序中类名Set又已确定,就能唯一确定the qualified name: java.util.Set


程序怎么写?理论上我也知道。 --------------------编程问答-------------------- 正则何如.. --------------------编程问答-------------------- 编译后的class文件是没有import的 --------------------编程问答-------------------- 这东西要得到你得了解java编译成class文件后的特点了。 --------------------编程问答--------------------
引用 11 楼 dxqrr 的回复:
编译后的class文件是没有import的


引用 12 楼 suciver 的回复:
这东西要得到你得了解java编译成class文件后的特点了。


找了几天,发现有三个东西是可行的:

反射:但得不到局部的变量引用的类。
eclipse ast: 只是分析出每一行代码,并不能得到代码所引的类的全名。
asm:是中间字节码,现在正在研究中。。。。 --------------------编程问答-------------------- 这里有个例子(看采纳答案)

http://stackoverflow.com/questions/3845823/getting-list-of-fully-qualified-names-from-a-simple-name --------------------编程问答--------------------
引用 14 楼 dracularking 的回复:
这里有个例子(看采纳答案)

http://stackoverflow.com/questions/3845823/getting-list-of-fully-qualified-names-from-a-simple-name


这个里面,写的方法里调用的类,都不找不是哪里的。 --------------------编程问答--------------------
引用 13 楼 tuxming 的回复:
引用 11 楼 dxqrr 的回复:编译后的class文件是没有import的

引用 12 楼 suciver 的回复:这东西要得到你得了解java编译成class文件后的特点了。

找了几天,发现有三个东西是可行的:

反射:但得不到局部的变量引用的类。
eclipse ast: 只是分析出每一行代码,并不能得到代码所引的类的全名。
asm:是中间字节……


LZ还在纠结啊,如果你要分析字节码,就用 javap -c -verbose [CLASS NAME] 命令就足够好使了

--------------------编程问答-------------------- 需要写这样一个小工具出来,差不多已经做完了。

今天上来结下贴子。但是还有些问题没有解决,在此标记希望大神过来帮忙 --------------------编程问答-------------------- 最终是得用的asm的完成这个任务的。

如下:
main 方法:

public static Set<String> main(String[] args) throws IOException{
//xm.referencepackage.views.ReferencePackageView 需要解析的类名。fullname
ClassReader cr = new ClassReader("xm.referencepackage.views.ReferencePackageView"); 
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); 
        MyClassAdapter classAdapter = new MyClassAdapter(cw); 
        cr.accept(classAdapter, ClassReader.SKIP_DEBUG); 
        
        Set<String> pkgs = classAdapter.getPackages();
        
        return pkgs;
}


MyClassAdapter  继承:ClassVisitor


import static org.objectweb.asm.Opcodes.ASM4;

import java.util.HashSet;
import java.util.Set;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.tree.MethodNode;


public class MyClassAdapter extends ClassVisitor{
private Set<String> packages = new HashSet<String>();

public MyClassAdapter(ClassVisitor cv) {
super(ASM4,cv);
}

public Set<String> getPackages(){
return packages;
}

public void visit(int version, int access, String name, String signature, String superName, String[] interfaces){
//打印出类的一些基本信息
System.out.println("version:"+version+" access:"+access+" name:"+name+" signature:"+signature+" superName:"+superName);
}

//访问全局变量
public FieldVisitor visitField(int access, String name, String desc,
      String signature, Object value) 
{
//
    System.out.println("Field:"+name+" desc:"+desc+" signature:"+signature+" value:"+value);

    return cv.visitField(access, name, desc, signature, value);
}
//访问方法
public MethodVisitor visitMethod(int access, String name,
      String desc, String signature, String[] exceptions){

System.out.println("Method:"+name+" desc:"+desc+" signature:"+signature+" exceptions:"+exceptions);

//访问方法体
MethodBodyAdapter mba = new MethodBodyAdapter(ASM4,access,name,desc,signature,exceptions,this.packages);

return mba;
}
//访问类注解
public AnnotationVisitor visitAnnotation(String name,
boolean visible){

System.out.println("Annotation:"+name+" desc:"+visible);

return cv.visitAnnotation(name, visible);
}

}



MethodBodyAdapter 继承: MethodNode


import java.util.Iterator;
import java.util.Set;

import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;

public class MethodBodyAdapter extends MethodNode   {
private Set<String> packages = null;

public MethodBodyAdapter(int api, int access, String name, String desc, String signature, String[] exceptions,Set<String> packages){
super(api, access, name, desc, signature, exceptions);
this.packages = packages;
}

public Set<String> getPackages(){
return packages;
}
//访问每条代码段:
public void visitInsn(int opcode){
System.out.println("visitInsn:"+this.name);
Iterator<AbstractInsnNode> itr = this.instructions.iterator(0);
while (itr.hasNext()) {
AbstractInsnNode insn = itr.next();

switch (insn.getType()) {
case AbstractInsnNode.FIELD_INSN:{
//System.out.println("FIELD_INSN:"+AbstractInsnNode.FIELD_INSN);
String pkg = ((FieldInsnNode) insn).desc;
System.out.println(desc);
}
break;
case AbstractInsnNode.METHOD_INSN :{
//System.out.println("METHOD_INSN:"+AbstractInsnNode.METHOD_INSN);
System.out.println(((MethodInsnNode) insn).owner);
}
break;
case AbstractInsnNode.TYPE_INSN :{
//System.out.println("TYPE_INSN:"+AbstractInsnNode.TYPE_INSN);
System.out.println(((TypeInsnNode)insn).desc);
}
break;

// case AbstractInsnNode.VAR_INSN :{
// System.out.println("VAR_INSN:"+AbstractInsnNode.VAR_INSN);
// VarInsnNode vinsn = ((VarInsnNode) insn);
//
// }
// break;
//
// case AbstractInsnNode.LABEL :{
// System.out.println("LABEL:"+AbstractInsnNode.LABEL);
// LabelNode label = (LabelNode) insn;
// }
// break;
//
// case AbstractInsnNode.LDC_INSN :{
// System.out.println("LDC_INSN:"+AbstractInsnNode.LDC_INSN);
// LdcInsnNode ldc = (LdcInsnNode) insn;
// }
// break;

default:
break;
}

}
}

}




如上可以基本得到所有引用的类:目前测试到下面一种情况的引用类得不到:
在方法体里面,如下代码片段:

List<SomeClass> list = new ArraryList<SomeClass>();
list.add(SomeClassGenerator.getSomeClass);

这个SomeClass得到不。

求大神指定 ,在此标记。


--------------------编程问答-------------------- 我也不知道啊
补充:Java ,  Java EE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,