黑马程序员-------基础加强2

来源:互联网 发布:sql的九个常用语句 编辑:程序博客网 时间:2024/04/30 02:04

框架概念:
框架概念就是先事先规定要一些规则,比如说类名,方法名等一些参数. 然后我们在延伸着事先规定好的路线, 用规定要的名字来创建相应的功能.

 

内省概念:IntroSpector
JavaBena就是一种类定义规则,
JavaBena的规则:所有的一级方法,全部都是以get 和set来命名, 比如 getAge  setAge . 把get或set去掉得到的就是所有的属性名 . 属性名命名有个规则就是.如果第二个字母为小写那么就把第一个字母也变成小写.
PropertyDescription:是一个类,叫属性描述符
 Method getReadMethod()
          获得应该用于读取属性值的方法。
 Method getWriteMethod()
          获得应该用于写入属性值的方法。
-----------------------------------------------------------------------------------
简易Bena:
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class JavaBean
{
 public static void main (String...args) throws Exception
 {
  Preson p=new Preson(10);
  String GetName = "age";
  PropertyDescriptor pd=new PropertyDescriptor(GetName,p.getClass());
  Method md = pd.getReadMethod();
  Object obj = md.invoke(p);
  System.out.println(obj);
 }
}
class Preson
{
 Preson(int age)
 {
  this.age = age;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 private int age;
}

--------------------------------------------------------------------------------------
beanUtils工具包,
给他int 他操作的是String,最后返回的还是int
小知识点:在复写Object时候后面传值要写(Object obj) 如果没这么写那就不是覆盖,是从载.

1.5新特性!:注解@
注解就是把自己定义的标记传递给编译器.然编译器遵守这个规则来运行编译.要注意,注解是类.加载到类的字节码里
注解的生命周期有三个阶段,
1:源文件, RetetionPollcy.SOURCE
2:calss(默认)RetetionPollcy.CLASS
3:运行时RetetionPollcy.RUNTIME
@Deprecated(过时)
@SuppressWarnings(压缩警告)
@Overreide(覆盖)
字节码.isAnnotationPresent(注解类行.class),判断类是否有指定的注解. 返回逻辑型
字节码.getAnnotation(注解类行.class)获取这个注解类的实体对象,返回的就是对象
给注解添加注解的时候回用到的字段
ElementType.Type   限定这个注解只能用于某些方法
注解加强:
怎么为注解添加属性,
在自定义注解的时候,可以给注解添加接口方法,如 color (String),value(String)  , arrayAttr(int[]),   格式为,返回类型空格 属性名().可以把枚举(Enum)当成类型.也可以把把注解(EmtaAnnotAtion)当存属性添加进来
然后在调用这个注解的时候,就需要给这些方法赋值,也就是为注解添加属性, 在给自定义注解添加接口方法的时候,可以直接把这些属性设置成缺省.这样他就有了默认的属性信息.调用的时候,可以不设置带有缺省的属性,那么他就调用了事先设置好的被缺省的信息.
default(缺省)


1.5新特性:class有了新爸爸,  Type
1.5新特性:泛型
泛型是一种编译时期的安全机制,其实泛型就是一种类型限定, 一个容器在定义的时候就给它一个定义,只能存储事先定义的一类实物.这样就相当于给这个容器打一个标签.而这个标签用<>表示. 泛型的参数化标签,没有继承关系(Object和String不可以混合使用, 怎么混都不行).
泛型的问号通配符<?>
<?>就是表示不明确的数据类型, 他可以接受任何类型, 可以引用于参数化无关的方法,但是在编译器不能对接收的集合使用参数化的功能, 因为在编译之前根本不知道接收的具体是什么. . 通配符可以有超类子类的概念.
不规则通配符<T>:不规则通配符只能使用引用类型

 

类加载器getClassLoader().
getResourceAsStream(String name)
          返回读取指定资源的输入流。

类名.calss.getClassLoader().getResourceAsStream(String name) 返回一个IN流类类加载器:java中的每个类都需要通过一个特殊的类将其加载到内存中,这个特殊的类就是类加载器类ClassLoader

作用:将定义好的java类加载到内存中,并生成字节码文件,后续有系统对程序中类内部的代码进行操作

由于类加载器也是一个类,所以它也需要被其他的类加载器进行加载,但是最后肯定有一个最上级的类加载器不能再被java中类加载器类这样的类加载器加载,则这个最上层的类加载器就是BootStrap

java中提供了3种类加载器,分别用于加载不同位置的类

BootStrap 这个就是最上层的类加载器,它不是一个java类,而是一个嵌入在java虚拟机中的一个由c++编写的二进制程序,
 当虚拟机启动时,这个类加载器就已经被启动。
 它加载的是JRE/lib/rt.jar 中的类文件,基本都是java内部定义的类文件
ExtClassLoader 它加载的是JRE/lib/ext/*.jar 中的类文件,这是一个扩展的类文件夹
AppClassLoader 加载ClassPath指定的所有jar和目录下的类文件。也就是用户自定义的类文件

结构关系 AppClassLoader < ExtClassLoader < BootStrap

类加载器的委托机制
当java虚拟机要加载一个类,
最先选择的是当前线程的类加载器去加载类中的第一个类,
当类A引用了类B,则会用类A的类加载器去加载类B
可以使用ClassLoader中的loaderClass()方法,去指定某个类加载器去加载类文件。
这个主要使用在自定义类加载器上

当类加载器被选定,会先去用这个加载器的上级去加载类文件,如果没有则继续向上查找,当到达BootStrap时也没找到,就会继续向下选定类加载器,直到最初被选定的类加载器。
例:选定AppClassLoader 则顺序为
ExtClassLoader > BootStrap > ExtClassLoader > AppClassLoader
如果选定的类加载器也没找到文件,则会ClassNotFoundException异常,而不会继续使用其下级类加载器。因为如果有多个子类
则不知道应该去使用哪个。

自定义类加载器:
 1.继承ClassLoader类
 2.覆写findClass()方法
 3.创建类加载器,指定其上级加载器,两种方法(构造传值、使用getSystemClassLoader()指定默认的上级)
 4.调用loadClass()方法去加载指定的类

3个重要方法:
 1.loadClass 加载指定的类
 2.findClass 查找指定的类 并返回该类的字节码文件
 3.defineClass 将指定的类数据(字节数组形式)转成字节码文件
原理:loadClass加载时,内部调用了findClass方法,findClass内部调用了defineClass方法

自定义加密类,并用自定义的类加载器去解密类文件并加载。
加密/解密算法
public static void cypher(InputStream ips,OutputStream ops) throws Exception
{
 int b;
 while((b = ips.read())!=-1)
 {
  ops.write(b^0xff);
 }
}

带解密功能的类加载器,覆盖findClass方法,内部代码体现
FileInputStream fis = new FileInputStream(类文件路径);
ByteArrayInputStream baos = new ByteArrayOutputStream();
cypher(fis,baos);
byte[] bytes = baos.toByteArray();
return defineClass(null,bytes,0,bytes.length);

 


动态代理. 首先用 Proxy.getProxyClass方法获取了代理类的class对象,getProxyClass所用到的参数是,(类加载器,同一个接口.)所有用getProxyClass获取得到的class对象都只有一个参数就是InvocationHandler
----------------
InvocationHandler是一个接口,可以用内部类的方法直接创建这个接口的子类,也可以new一个出来
----------------
假设这个calss对象的名字是clazz  .
那么现在可以用getConstructor的方法再把InvocationHandler.class 作为参数传递给getConstructor .    这样就可以得到完整的构造函数, 最后再用这个完整的构造函数创建对象.这就是一个动态代理类了.
------------------------------------------
第二种方法也就是简写方法.直接用
Proxy.newProxyInstance()方法来创建代理类对象.
需要传递三个参数,第一个还是加载器,第二个还是接口,第三个是直接给一个InvocationHandler. 同样可以直接new InvocationHandler的匿名内部类.
------------------
InvocationHandler是一个接口, 这个接口里复写了invoke,.  handler的invoke.用于连接代理类和被代理类,一般在handler复写的invoke的内部来使用method的invoke来实现方法,用一个object对象来接受,然后返回这个object对象,如果被代理对象创建在handler的invoke外,那么代理对象就是固定的.每次运行代理类都是相当于在运行同一个被代理类...

原创粉丝点击