Java--反射的逐步理解
层层引入反射的作用
一.类类型的概念:所有类都是对象,是Class类的实例对象,这个对象我们成为该类的类类型
1.下面是一个小的test,以产生3种方式的类类型:
public class test {
/**
* @param args
*/
public static void main(String[] args) {
foo user = new foo();
//任何一个类都包含一个隐含的静态成员变量class
Class c1 = foo.class;
Class c2 = user.getClass();
Class c3 = null;
try {
c3 = Class.forName("test.foo");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//c1 c2,c3是foo类的类类型
}
class foo{ void print(){ System.out.println("haha"); } }
2.其实数据类型也有自己的类类型
Class class1 = int.class;//int的类类型
Class class2 = String.class;
Class class3 = double.class;
Class class4 = Double.class;
System.out.println(class1);
System.out.println(class2.getSimpleName());
System.out.println(class3);
System.out.println(class4);
3.类类型可以创建类的实例对象
try {
foo h =(foo)c1.newInstance();//类类型可以创建该类的实例对象
//需要有无参数的构造方法
h.print();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
二.动态加载类
1.我们有这样的疑惑,如果一个主函数中有好多个类,其中有一个类出现错误,其他类都没法用,所以我们就想我们要用那个类就让那个类运行,并且不想在重新编译主类,这时候动态加载类就派上了用场,不用动态类的时候会出现类似这样的问题:

当然这种情况只会出现在我们手动采用javac编译导致的,开发工具让我们看不到这些细节的东西。.
2.我们先引出动态加载类的概念,class.forName("")是动态加载类,而new class()是静态加载类,本质区别是,静态加载类的时候,编译时类必须存在,而动态加载类不一定存在。
public class sum {
public static void main(String[] args) {
try
{
//动态加载类
//args[0]表示的是在main方法里面传进来的第一个参数
Class c = Class.forName(args[0]);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
三.类对类的操作
1.通过Method类获取成员方法
/**
* 获取成员方法
* Method类,方法对象
* 一个成员方法就是一个Method对象
* getMethods()方法获取所有的public的函数,包括父类继承而来的
* getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
* @param obj
*/
public static void printClassMessage(Object obj) {
Class c1 = obj.getClass();
System.out.println(c1.getName());
Method[] ms = c1.getMethods();//c.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].getParameterTypes();
for (Class class1 : paramTypes) {
System.out.println(class1.getName());
}
System.out.println(")");
} }
2.通过Field类获取成员变量
/**
* 获取成员变量
* 成员变量也是对象
* java.lang.reflect.Field
* Filed类封装了关于成员变量的操作
* getFileds()方法获取的是所有的public的成员变量的信息
* getDeclaredFiled获取的是该类自己声明的成员变量的信息
* @param obj
*/ public static void printFieldMethod(Object obj) {
Class c1 = obj.getClass();
Field[] fs =c1.getDeclaredFields();
for (Field field : fs) {
//得到成员变量的类型的类类型
Class fieldType =field.getType();
String typeName = fieldType.getName();
//得到成员变量的名称
String fieldName=field.getName();
System.out.println(typeName+" "+fieldName);
}
}
3.通过Constructor类获取构造函数
/**
* 打印对象的构造函数的信息
* java.lang.Constructor中封装了构造函数的信息
* getConstructors获取所有的public的构造函数
* getDeclaredConstructors得到所有的构造函数
* @param obj
*/
public static void printConMessage(Object obj){
Class c = obj.getClass();
//Constructor cs = c.getConstructors();
Constructor[] cs =c.getDeclaredConstructors();
for (Constructor constructor : cs) {
System.out.println(constructor.getName()+"(");
Class[] paramTypes =constructor.getParameterTypes();
for (Class class1 : paramTypes) {
System.out.println(class1.getName()+",");
}
System.out.println(")");
}
}
四.反射
1.反射的作用是指定方法名称调用方法,demo如下:
public class demo {
public static void main(String[] args) {
//获取类的信息,就得先获取类的类类型
A a1 = new A();
Class c1 = a1.getClass();
/*
* 获取方法,名称和参数列表来决定
* getMethod获取的是public的方法
* getDelcaredMethod获取的的是自己声明的方法
*
*/
try {
Method method = c1.getMethod("print", int.class,int.class);
/*
* 方法的反射操作
* a1.print(10,20);方法的反射操作是用m对象来进行方法调用和a1.print调用的效果相同
* 方法如何没有返回值返回null,有返回值返回具体的返回值
* ...表示有几个参数传几个
*/
Object object =method.invoke(a1, 10,20);
Method method2 =c1.getMethod("print", new Class[]{String.class,String.class});
method2.invoke(a1, "hello","world");
Method method3 =c1.getMethod("print",null);
Object a = method3.invoke(a1);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class A{
public void print() {
System.out.println("hello world");
}
public void print(int a,int b){
System.out.println(a+b);
}
public void print(String a,String b){
System.out.println(a.toUpperCase()+b.toLowerCase());
}
}
2.案例,通过标准JavaBean的属性名获取其属性值
五.泛型
1.泛型是什么?看下面两个声明
//只能传String类型的数
ArrayList<String> list = new ArrayList<String>();
ArrayList list2 = new ArrayList();
2.泛型的本质,看下面的demo
public class fanxing {
/**
* 通过Class,Method来认识泛型的本质
* @param args
*/
public static void main(String[] args) {
//只能传String类型的数
ArrayList<String> list = new ArrayList<String>();
ArrayList list2 = new ArrayList();
list.add("hello");
//list.add(20);
Class c1 = list.getClass();
Class c2 =list2.getClass();
System.out.println(c1==c2);
}
}
由运行结果可以得出下面结论:
反射的操作都是编译之后的操作
c1==c2结果返回true说明编译之后的泛型是去泛型化的
Java中集合的泛型,是防止错误输入的,只是在编译阶段有效
3.利用方法的反射来操作,绕过编译
try {
Method a1 =c1.getMethod("add", Object.class);
Object a2 = a1.invoke(list, 2);
System.out.println(list.size());
System.out.println(list);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
代码的运行结果验证了泛型,得出结论,绕过编译操作就绕过了泛型
最后谢谢大家的阅读
Java--反射的逐步理解的更多相关文章
- JAVA反射机制及理解
JAVA反射 往往当我们面对一项新的知识时,我们往往需要知道三个方面,它是什么,它能做什么,它比原有知识强在哪里,我们该怎么使用它.当你能够解决这些问题时,便意味着你已经对这项知识入门了. 首先: 反 ...
- Java反射的浅显理解
一.回顾反射相关的知识 1.在xml文件中使用反射的好处: 1)代码更加灵活,后期维护只需要修改配置文件即可 · 初学者一般习惯于在代码本身上直接修改,后期也可以修改配置文件达到相同的目的 · 修改配 ...
- 我对java反射机制的理解
我们平常怎么用一个使用类,怎么使用类的方法?其实就是创建一个对象,并且通过这个对象调用这个方法.不过这有一个问题,就是这个对象的载体就和这个对象产生了耦合,怎么降低两者间的耦合呢?java的反射机制就 ...
- java反射机制的理解
反射机制是什么概念?大多都有介绍,指的是程序在运行状态中,能够加载一个只有类名的类,加载完之后会在堆上产生一个Class对象.通过这个 Class对象可以获得类的属性.方法和其他类信息.之前对反射的应 ...
- java反射的初理解
反射 获取类的方法: Class<?> aClass1 = Class.forName("TestDemo.refection.User");//通过类路径获取 Cla ...
- Java反射的一些理解
1.Class对象 VS. 实例对象 在Java中我们一般是这样使用类的:编写类,然后new对象,再调用方法.这里new出来的对象暂且称之为实例对象(instance).其实在这之前还涉及到一个Cla ...
- JAVA反射机制_获取字节码文件对象
是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称为java语 ...
- Java反射机制获取Class文件
JAVA反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象方法的功能称为 ...
- java反射机制 + Method.invoke解释 getMethod + 反射理解
功能: 通过读取另一个Dll去创建一个控件(Form,Button,TextBox,DataGridView),然后对当中一些属性进行检查. 创建控件的大致流程是,Assembly->Modul ...
- (转)JAVA反射机制理解
JAVA反射机制: 通俗地说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,希望读者能理解,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们. 理论的东东太多也没 ...
随机推荐
- c++ thread
Either pthread_join(3) or pthread_detach() should be called for each thread,that an application crea ...
- 扔掉log4j、log4j2,自己动手实现一个多功能日志记录框架,包含文件,数据库日志写入,实测5W+/秒日志文件写入,2W+/秒数据库日志写入,虽然它现在还没有logback那么强大
讲到log4j,现在国外基本是没有开发者用这个框架了,原因大致有几点,1.功能太少:2.效率低下:3.线程锁bug等等等各种莫名其妙的bug一直都没解决. 其实最重要的是log4j的作者自己也放弃了l ...
- .NET和JAVA 反射对比
反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等程序集内部的信息.使用反射可以看到一个程序集内部的接口.类.方法.字段.属性.特性等等信息.在System.Reflectio ...
- windows环境下使用virtualenv对python进行多版本隔离
最近在用python做一个文本的情感分析的项目,用到tensorflow,需要用python3的版本,之前因为<机器学习实战>那本书的缘故,用的是python2.7.所以目前的情况是要两个 ...
- AngularJS高级程序设计读书笔记 -- 指令篇 之 内置指令
1. 内置指令(10-12 章) AngularJS 内置超过 50 个内置指令, 包括 数据绑定,表单验证,模板生成,时间处理 和 HTML 操作. 指令暴露了 AngularJS 的核心功能, 如 ...
- .net 4.0 中的特性总结(三):垃圾回收
1.内存基础知识 每个进程都有其自己单独的虚拟地址空间. 同一台计算机上的所有进程共享相同的物理内存,如果有页文件,则也共享页文件. 默认情况下,32 位计算机上的每个进程都具有 2 GB 的用户模式 ...
- MongoDB一个基于分布式文件存储的数据库(介于关系数据库和非关系数据库之间的数据库)
1:MongoDB的官方网址:https://www.mongodb.com MongoDB的中文社区:http://www.mongoing.com/(老外也很看重中国市场啊,知道大家英语不好, ...
- 关于MATLAB处理大数据坐标文件
原先有3000条测试数据,MATLAB表现出来强大的数据处理能力,十几秒就可以把数据分类.分装并储存,这次共有10万条坐标数据,MATLAB明显后劲不足,显示内存不足 自我认识:以前MATLAB数据处 ...
- request.getParameter()及解决数据库中文乱码问题——实习第七天
今天老师让我们自己做一个小项目,我开始着手于实现这个小项目.途中遇到过几个小问题,在此做个小记录, 相信后期还是会借鉴的. 1,从前台传入数据给后台传入数据,并没有传入成功: 输出的为Null. 当然 ...
- php倒计时防刷新
<?php //php的时间是以秒算.js的时间以毫秒算 date_default_timezone_set("Asia/Hong_Kong");//地区 //配置每天的活动 ...