关于反射重新讲解01-05-2015

来源:互联网 发布:日剧推理 知乎 编辑:程序博客网 时间:2024/06/06 07:49

1、题外话:回顾内容感想

a、思想上要更多考虑我去做什么事,而不是想怎么做

java编程中利用集合的思想。

b、分析问题—>解决问题——问题抽象化

多次这样思考之后会形成一定的思路

3、java中类之间的访问:

继承的类关系要在语义上面说的通吗?

一、理论知识

1、JDBC访问数据库的6个步骤,注意关闭。

2、数据库访问:JDBC + 反射

3、反射: public class 用于定义类,小class

Class类的实例表示正在运行的Java应用程序中的类和接口。

反射:Class类的实例:表示是所写的字节码文件(.class文件),获得".class"类文件可以去做任何事情,也可以包含所有东西。

Class类定义了:如何去创建一个类或接口。

构造函数:说明构造函数是否能成功调用完毕,标志着这个对象创建的成功与失败。

Class无构造函数,不能创建对象(new),可以间接的创建Class对象。通过其中的静态的方法(共有、教师)返回一个对象(jvm-java虚拟机创建)

接上:Class对象有虚拟机创建,故底层创建对象不一定需要通过构造器。通过构造器来创建对象时java要求程序员创建。

ps:只要不是抽象类,都可以创建对象。一般创建对象要有构造函数,

4、对Class操作代码:

A、创建Class对象:

package test;public class Reflect {public static void main(String[] args) throws ClassNotFoundException {//通过抽象的方法返回一个Class对象,这样我们就可以调用Class中的所有方法了。Class clazz = Class.forName("test.Stuff");//这里的参数要写完全限定名(包名.类名)System.out.println(clazz.getName());//结果:test.StuffSystem.out.println(clazz.getSimpleName());//结果:Stuff}}
B、利用新建的Class对象使用Class类中所有的方法:举例
<span style="white-space:pre"></span>System.out.println(clazz.getModifiers());System.out.println(clazz.getDeclaredConstructors());System.out.println(clazz.getDeclaredFields());System.out.println(clazz.getSuperclass());System.out.println(clazz.getInterfaces().length);System.out.println(clazz.getDeclaredMethods());
C、创建Class对象的三种方法:本质是一样的,没有区别
package test;public class Reflect {public static void main(String[] args) throws ClassNotFoundException {Class clazz = Class.forName("test.Stuff");//这里的参数要写完全限定名(包名.类名)Class clazz1=Stuff.class;//三种不用的途径获得jvm中的.class文件Class clazz2=new Stuff().getClass();System.out.println(clazz == clazz1);//"=="判断值类型值是否相等,引用类型地址是否相等(是不是同一块地址的东西)。System.out.println(clazz == clazz2);//"equal"判断引用类型其地址中的内容是否相等}}

D、newInstance():创建Class对象。通过阅读API要学会看使用方法,通过最基本的面向对象知识。反射创建对象

Object o=clazz.newInstance();//new Employee()
两种创建对象上没有区别:前一种是jvm创建对象,后一种是程序员创建对象。

5、类的组成部分:属性、构造函数、方法(修饰符:public...)

A、构造器:Construct

先获得大Class类相当于获得.class文件,然后才能对里面属性、方法、构造器的内容进行操作。即我拥有了.class类的所有内容,我可以利用API对类中的所有东西进行操作。java.lang包和java.lang.reflect

Construct类: final    定义构造器的写法(与Class一样),不允许继承或修改。java.lang.reflect

每个类的构造器都是Construct类的对象实例。

Class<?>...:必须为Class类型

a:Construct类中newInstance(Object... initargs)的方法:有参数:构造函数本身就有有参构造。

通过构造器创建的对象,正规创建对象。jvm创建对象。

System.out.println("-------------------------------------------------------------");Constructor[] c1=clazz.getConstructors();//获取构造器的途径,多态?Constructor[] c2=clazz.getDeclaredConstructors();System.out.println(c1.length);System.out.println(c2.length);Constructor c=clazz.getDeclaredConstructor(String.class,String.class);System.out.println(c.getModifiers());System.out.println(c.getName());System.out.println(c.getExceptionTypes());System.out.println(c.getParameterTypes());Object o1=c.newInstance("xxx","123");//new Employee("xxx","123");这两种方法创建对象没有区别。//Object o1=c.newInstance();System.out.println("TestReflect.main()"+o1);Object o2=clazz.getDeclaredConstructor().newInstance();//clazz.newInstance()是一种简写方式System.out.println("TestReflect.main()"+o2);

B、属性Field:类或接口中属性的信息

类中所有的属性都是Field的对象实例。

先获得大Class类相当于获得.class文件,然后才能对里面属性、方法、构造器的内容进行操作。即我拥有了.class类的所有内容,我可以利用API对类中的所有东西进行操作。java.lang包和java.lang.reflect

<span style="white-space:pre"></span>Field f = clazz.getDeclaredField("name");f.setAccessible(true);System.out.println(f.getName());//属性名System.out.println(f.getModifiers());//修饰符System.out.println(f.get(o));f.set(o, "zhangsan");System.out.println(f.get(o));//设置属性值System.out.println(((Stuff)o).getName());//设置属性值,上面两个方法同一种方式
C、Method方法:

独有的两个方法:getReturnType();invok();

先获得大Class类相当于获得.class文件,然后才能对里面属性、方法、构造器的内容进行操作。即我拥有了.class类的所有内容,我可以利用API对类中的所有东西进行操作。java.lang包和java.lang.reflect

//第一个参数方法名称,后面是方法形参列表。Class<?>仅仅只是泛型约束,只要填充符合类型的参数列表即可clazz.getDeclaredMethods(String name, Class<?>...);//先从对象中拿到方法之后(java.lang),才有对方法进行的操作(java.lang,reflect)
代码:
<span style="white-space:pre"></span>Constructor c =clazz.getDeclaredConstructor();//66666666666666<span style="white-space:pre"></span>Object o =c.newInstance();//666666666666666<span style="white-space:pre"></span>//获取特定的方法:<span style="white-space:pre"></span>Method m =clazz.getMethod("test", String.class);//Class<?>传参数注意,意思传进这个集合的泛型约束<span style="white-space:pre"></span>//对于方法的操作都是选择特定的方法之后,才是对方法进行操作。所以invoke()执行方法时要注意,你选择的方法的参数与invok()中的参数要统一,<span style="white-space:pre"></span>//不然在最后两条语句执行时,会爆出参数不匹配的错误<span style="white-space:pre"></span>System.out.println(m.getModifiers());//修饰符<span style="white-space:pre"></span>System.out.println(m.getDefaultValue());<span style="white-space:pre"></span>System.out.println(m.getName());<span style="white-space:pre"></span>System.out.println(m.getParameterCount());<span style="white-space:pre"></span>System.out.println(m.getClass());//<span style="white-space:pre"></span>//m.invoke(o);<span style="white-space:pre"></span>m.invoke(o,"dddd");
b、invok():

方法的执行,要通过对象的调用。

invok()中要传递参数:第一个为对象。第二个传方法的参数。注意:invok()中的参数要与clazz.getMethod(String name, Class<?>...)中的保持一致,即调用方法的对象中参数保持一致,否则会报错。

6、反射总结:

在java.lang.Class和java.lang.reflect包中Class、Construct、Method、Field修饰符为final这些都表示类、构造器、方法、域都是这个类的对象。所以这几个就是java中为什么我们定义的类、构造器、方法、域都是相同的原因。

二、总结

Java中如何利用API解决问题:

比如员工管理系统中对于ResultSet的处理:首先根据基本知识:ResultSet数据库部分,因此应该在java.sql包下面找到ResultSet接口,

然后在相应的API中找到有没有解决我们问题的方法。


0 0