怎么得到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 --------------------编程问答-------------------- 反射拿不方法里面的类型申明。 --------------------编程问答--------------------
反射后你用getGenericReturnType取返回值类型看看,别用getReturnType --------------------编程问答-------------------- 1, Java在编译的时候,Date是什么类型,会把Full-name,编译到.class中,
写成 Date只是给程序写着和看着方便的,换句话,你不可能不知道它的具体类型是什么。
2. 没太明白你关心什么,但是反射是可以得知一个类型是否是 泛型类的。
3. 肯定要引入了。
4. --------------------编程问答--------------------
我就是要得到一个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这个字符串。
--------------------编程问答--------------------
总算大概明白你的困惑在那里了。生成CLASS字节码的时候JVM把类型都确定完了,字节码里没import。
你反射也反射不出来import是怎么写的的。
你要的东西就是
System.out.println(Info.class.getClasses());
所有引用到的类都会返回,具体可以看getClasses()的注释:
--------------------编程问答-------------------- import时包名 java.util已确定,下面程序中类名Set又已确定,就能唯一确定the qualified name: java.util.Set --------------------编程问答--------------------
按照你说的:
Class<?>[] cs = Info.class.getClasses();
System.out.println(cs.length);
输出是:0 --------------------编程问答--------------------
程序怎么写?理论上我也知道。 --------------------编程问答-------------------- 正则何如.. --------------------编程问答-------------------- 编译后的class文件是没有import的 --------------------编程问答-------------------- 这东西要得到你得了解java编译成class文件后的特点了。 --------------------编程问答--------------------
找了几天,发现有三个东西是可行的:
反射:但得不到局部的变量引用的类。
eclipse ast: 只是分析出每一行代码,并不能得到代码所引的类的全名。
asm:是中间字节码,现在正在研究中。。。。 --------------------编程问答-------------------- 这里有个例子(看采纳答案)
http://stackoverflow.com/questions/3845823/getting-list-of-fully-qualified-names-from-a-simple-name --------------------编程问答--------------------
这个里面,写的方法里调用的类,都不找不是哪里的。 --------------------编程问答--------------------
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