标签:反射 Java getName System class print Class out
Class类
Java里面有两个不是类,1基本数据类型 2static成员
任何一个类都是java.lang.Class类的实例对象。表达方式如下3种:
1 Class c1= Foo.class; 任何一个类都有一个隐含的static成员变量class
2 Class c2=foo1.getClass(); c1 c2是Foo类的类类型(class type)
3 Class c2=null; c3=Class.forName("类的全称***.Foo");
一个类是Class的一个对象,c1=c2=c3
Class类的构造方法是私有的,不能像普通类一样new一个对象。只有JVM可以创建Class的对象。
可以通过类的类类型创建类的对象,即Foo foo=(Foo)c1.newInstance(); 前提是Foo有无参构造方法
动态加载类
动态vs静态加载 即 运行时加载 vs 编译时加载
上面c3的建立方式就是动态加载类。Class.forName("类全称") 然后c3.newInstance();
new是静态加载, 编译时就加载所有可能使用到的类,无论是否真的用。
功能性的类应该尽量使用动态加载。
获取类的方法信息
除了所有的类有.class,基本数据类型还有void关键字也有.class 类类型
Class c1=int.Class;
c1.getName(); c1.getSimpleName();//不含包名
Class类的基本API
public class ClassUtil{ public static void printClassMessage(Object obj){
Class c=obj.getClass(); //obj的类类型
System.out.print(c.getName());//类的名称
Method[] ms=c.getMethods();
//getMethods获得所有public方法,包括继承来的
//getDeclaredMethods获得所有自己生命的方法,无论访问权限是什么,没有继承的
for(int i=0;i<ms.length;i++)
{
Class returnType=ms[i].getReturnType()
System.out.print(returnType.getName()+" ");
System.out.print(ms[i].getName()+"(");
Class[] paramTypes=ms[i].getParamTypes();
for(Class c:paramTypes)
{
System.out.print(c.getName()+",");
}
System.out.println(")");
}
//===============================================
Field[] fs=c.getDeclaredFields();
for(int i=0;i<fs.length;i++)
{
Class type=fs[i].getType();
System.out.print(type.getName()+" ");
Class name=fs[i].getName();
System.out.println(name.getName());
}
//===============================================
Constructor[] cs=c.getDeclaredConstructors();
for(Constructor constructor:cs)
{
System.out.print(constructor.getName()+"(");
Class[] params = constructor.getParamTypes();
for(Class p:params)
System.out.print(p.getName()+",");
System.out.println(")");
}
}
}
获取类的成员变量信息
成员变量是java.lang.reflect.Field类的对象。
getFields()
getDeclaredFields()
区别同getMethods vs getDeclaredMethods
获取类的构造函数信息
getConstructors() getDeclaredConstructors() 所有的构造函数(构造函数都是要自己声明的)
构造函数是java.lang.Contructor类的对象。
总之,要先得到类的类类型,在得到类其中的信息。
方法的反射
1 获取类类型
2 获取方法名称+参数列表
method.invoke(对象,参数列表)
public class A(){ public void print(int a, int b){...} }
A a=new A();
Class c=a.getClass();
Method m = c.getMethod("print",int.class,int.class); //获取方法
Object o = m.invoke(a,10,20);
//方法反射: 用m对象来调用print函数,和a.print调用效果一样的!m.invoke返回方法的返回值。这里是null
泛型的本质
反射的操作都是编译之后即运行时的操作。
Java中集合的泛型是防止错误输入的,仅在编译阶段有效,绕过编译就无效了。反射嘛无效了就。
ArrayList list1= new ArrayList();
ArrayList<String> list2=new ArrayList<String>();
Class c1=list1.getClass(); Class c2= list2.getClass(); 可以试验发现c1==c2 true
Method m=c2.getDeclaredMethods("add", Object.class);
m.invoke(list2, 20); 这里就不报错类型错误了 int是不能自动转为String的
标签:反射,Java,getName,System,class,print,Class,out 来源: https://www.cnblogs.com/pylc/p/10534134.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。