------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
高薪技术:
一 静态导入:
1 定义:
1 1.5版本的新特性,可以导入一个类的所有静态成员。
2 静态导入后调用静态成员时前面可以不用加类名。
3 可以简化代码。
二 可变参数:
1 定义:
1 1.5版本的新特性。
2 可变参数是以数组的形式存在的,用类名...变量名表示。
3 一个方法只能有一个可变参数。
4 可变参数只能出现在参数的最后边。
2 例题:可变参数求和:
public class Test {
public static void main(String[] args) {
show(1,2,3,4,5);
}
public static void show(int...x){
int sum=0;
for(int in:x)
{
sum+=in;
}
System.out.println(sum);
}
}
三 增强for循环:
1 定义:
1 1.5版本新特性。
2 内部实现了迭代器,随意不可以增删操作。
3 使用简洁。
2 增强for例题:遍历数组:
public class Test {
public static void main(String[] args) {
int [] arr={1,2,3,4,5,6};
for(int in:arr)
{
System.out.println(in)
}
}
四 自动拆箱与装箱
1 定义:
1 1.5版本的新特性。
2 如需把基本类型直接付给包装类应用型变量。
3 也可直接用引用型变量做运算,变为基本数据类型。
4 提高了开发效率。
5 Integer利用了享源模式,在byte范围呢的数视为同意个对象。
2 自动拆箱与装箱例题:
public class Test {
public static void main(String[] args)
{
Integer x=2;
int y=x<<2;
System.out.println(y);
}
五 枚举:
1 定义:
1 枚举类值是常量。
2 不了以建立对象。
3 每个元素分别用一个公有的静态成员变量表示,都是一个对象。
4 可以有抽象方法。
5 必须实现Enum类。
6 不可继承其他类,也不能被其他类继承。
7 如果枚举只有一个值是,可以视作单利设计模式。
2 枚举例题:
public enum Dome {
AA(1) {
@Override
public void show() {
// TODO Auto-generated method stub
}
}
,BB(2) {
@Override
public void show() {
// TODO Auto-generated method stub
}
},CC(3) {
@Override
public void show() {
// TODO Auto-generated method stub
}
};
private qq(int x)
{
this.x = x;
}
int x=0;
public abstract void show();
五 反射:
1 定义:
1 反射是把Java类中的各个成分映射为JAVA类。
2 可以直接获取某类的所有成员。
3 是用来描述类的类。
六 Class类:
1 定义:
1 是所有字节码文件对象的父类。
2 一个类只有一份字节码文件。
3 只要是在源程序中出现的类型,都有各自的Class实例对象。
2 获取字节码的四种方式:
1 Class.forName("包名.类名")。
2 类名.class。
3 对象.getClass()。
4 基本数据包装类型.TYPE,获取内部包装的基本数据类型的字节码,只有基本数据类型的包装类有。
3 常见方法:
1 getDelaredconstructor(类型.class)
获取构造方法,并且可以获取私有。
2 getDelaredMethod(类型.class)
获取方法,并且可以获取私有。
3 getDelaredField()
获取属性,并且可以获取私有。
4 isArray()
是不是数组。
5 newInstance()
建立空构造函数的对象。
6 getName()
获取该类的名字。
7 isPrimtive()
是不是原始类型,就是是不是基本数据类型。
4 暴力反射:
1 Field,Method,Constructor,类里面的,setAccessible()方法。
2 暴力反射是指可以拿到类里面非共有的成员。
5 反射例题:通过反射建立对象将所有String类型属性值有a的全换成b。
public class Student {
private String str1="abc";
private int age;
private String str2="abcd";
private Student(String str1, int age, String str2) {
super();
this.str1 = str1;
this.age = age;
this.str2 = str2;
}
}
public class Test1 {
public static void main(String[] args) throws Exception {
Class<Student> c=Student.class;
Constructor<Student> con=c.getDeclaredConstructor();
con.setAccessible(true);
Student s=con.newInstance();
Field[] f1=c.getDeclaredFields();
for (Field f2:f1)
{
if(f2.getType()==(String.class))
{
f2.setAccessible(true);
String oldValue=(String)f2.get(s);
String newValue=oldValue.replace('a', 'b');
f2.set(s, newValue);
}
}
System.out.println(s);
}
}
七 Method 数组参数说明。
1 通过反射获取到方法时该方法的参数是数组,这时利用invoke方法设置执行会将数组打开按不再是以个参数, 会报错。
2 这时需要将所传参数封装到以个Object数组内该数组只能有一个参数,或者(object).
3 最要用于访问私有字段。
3 例题:
package itheitma
import java.lang.reflect.Method;
public class Test{
public static void main(String[] args) throws Exception {
Class c=Class.forName("itheitma.Test2");
Method m=c.getMethod("main",String[].class);
m.invoke(null, (Object)new String[]{"1","2","3",});
}
}
class Test2{
public static void main(String[] args) {
for(String s:args)
{
System.out.println(s);
}
}
}
八 数组的反射:
1 定义:
1 具有相同相元素类型,和具有相同元素的维的数组是同一种数组类型。
2 基本数据类型不是Object类型,所以不能赋给参数为Object[]类型。
2 特点及应用重点:
1 int [] 是指以个数组内部主观的都是整数类型。
2 Object[] 一个数组内部可以装Object类型。
3 所以Object[] obj=new int[1];是不可以的,
4 因为int[] 父类是Object 所以Object obj=new int[1];是可以的;
5 也就是说Object[] 是Object的子类。
6 将基本数据类型转换为集合后集合内只有一个int数组对象。
7 ArrayClass: 对数组反射操作的类。
8 ArrayClass.getLength()获取数组的长度。
九 JavaBean:内省
1 定义:
1 是一个特殊的Java类。
2 一个类内部有符合get..set..方法的类可以称之为javaBean。
3 根据成员方法获取和设置属性。
2 书写规则:
1 Age --> 如或第二个字母是小写将第一个字母改为小写,age()
2 AGe-->如果第二个字母为大写这不改变,AGe()。
3
两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例 对象通常称之为值对象(Value Object,简称VO)。
这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的 方法来访问。
3 对JavaBean的操作。
public class Test {
public static void main(String[] args)throws Exception
{
PropertyDescriptor p=new PropertyDescriptor("age", Student.class);
Method m=p.getReadMethod();
Object o=m.invoke(new Student("张三",20));
System.out.println(o.getClass());
Student s2=new Student("李四",(int)o);
p.getWriteMethod().invoke(s2,1 );
System.out.println(s2);
}
}
十 注释Annotation:
1 定义:
1 也是以个类,使用注解就相当于创建了以个实例对象。
2 是以种标记,用于告诉编译器一些信息。
3 可以自定义注解,需要继承与Annotation类。
2 Java自带常见注解:
1 @Deprecated
该注解的作用是标记某个过时的类或方法。
2 @Override
该注解用在方法前面,用来标识该方法是重写父类的某个方法。
3 @Retention
它是被定义在一个注解类的前面,用来说明该注解的生命周期。
3 注解的理解:
注释相当于一种标记,在程序中加了注释就等于为程序打上了某种标记 ,没加则等于没有标记,Javac编译 器,开发工具和其他程序可以用反射来了解类及各种元素上有无何种标记,看有什么标记,就干相应的是4, 标记快可以加在,包,类,字段,方法,方法参数以及局部变量上。
4 自定义注解:
1 想写接口以样写在前面加上@
2 可以定义属性格式为,返回值+变量名()。
5 使用注解
1 可以加在类,方法,字段,包,和参数上。
2 被作用成员.class.isAnntationPresent(自定义注解名)该成员具不具备该注释。
3 被作用的成员.class.getAnntation(自定义注解名)获取该注解对象。
4 @Retention(RetentionPolicy.RUNTIME)
元注解在注解类上定义,该注解类可以保留在运行时期,
他是枚举。
5 @Target(ElementType.Method)也是枚举元注解,该自定义注解可以作用在商法上。
6 Class的父类是Type@Target(ElementType.Method)可以加在类接口等上面。
6 注解属性:
1 格式:在注释类内定义类型名();因为很像接口所以定义成方法格式。
2 属性可以是String,数组,Class类型,枚举,也可以是注释。
3 在加注释的类上用方法变量名=赋值,也可以用default赋值。
4 可以通过注释对象调用这个方法获取值。
5 当数组值只有一个时大括号是可以省略的。
6 注释个特殊的属性value,如果只有一个value需要赋值时,value可以不用写。
7注解练习:定义一个注解类可以保留到运行时期,有一个返回值为Class类型属性,赋值为Student获取建立对象
import java.lang.reflect.Constructor;
@MyAnnotation(Student.class)
public class Test {
public static void main(String[] args) throws Exception {
MyAnnotation a=null;
a=(MyAnnotation) Test.class.getAnnotation(MyAnnotation.class);
Constructor<Student> c=a.value().getDeclaredConstructor(String.class,int.class);
c.setAccessible(true);
Student s=(Student) c.newInstance("张三",19);
System.out.println(s);
}
}
public class Student {
private String name;
private int age;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
private Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface MyAnnotation {
Class<Student> value() ;
}
十一 泛型
1 定义
1 1.5版本的新特性。最早应用于集合,可以限制集合存储同一类型。
2 当类中操作的引用数据类型不确定的时可以使用泛型定义。
3 类似于Object.
4 只在编译时期有效,编译后会去掉泛型,所以运行时期没有泛型。
5 泛型参数化不考虑继承。
2 泛型的好处:
1 可以将运行时期异常转到了编译时期。
2 避免了强制类型转换。
3 泛型应用:
1 泛型可以定在在类上。
2 泛型可以定义在方法上。
4 泛型术语:
1 ArrayList<E> 泛型类型。
2 ArrayList<E> 中的E称之为类型变量或类型参数。
3 ArrayList<Integer> 称之为参数化类型。
4 ArrayList<Integer> Integer称之为参数类型实例,实际类型参数。
5 <> 念typeof。
6 ArrayList 原始类型。、
5 通配符:
1 格式:<?>
2 表示可以传任意类信。
3 当定义了通配符参数时,在方法内不可以调用该对象与泛型参数有关的方法。
4 <? extends Number> 可以是Number 以下的类。
5 <? Super Integer> 可以使Integer的父类。
6 泛型例题:
1 通配符的使用注意事项。
public class Test1 {
public static void main(String[] args) throws Exception {
show(new ArrayList<Integer>());
}
public static void show(Collection<?> con)
{
con.add(1);//这是不可以的。add使用了泛型参数也就是说他可以传递任意类型。
con.size();//是可以的。 没有使用泛型定义。
con=new ArrayList<String>();//可以改变。
}
}
2 map集合的泛型使用:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test2 {
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<>();
map.put("张三", 20);
map.put("李四", 22);
map.put("王五", 23);
Set<Map.Entry<String, Integer>> set=map.entrySet();
for(Map.Entry<String, Integer> me:set)
{
System.out.println(me.getKey()+" "+me.getValue());
}
}
}
7 自定义泛型方法。
1 定义:
1 只能是表面不能完全实现。
2 具有类型推断。
2 定义在方法上:
泛型定义在返回值前面,在参数列表里传该泛型类型。
3 定义在类上:
1 泛型定义在类名后面。
2 返回值,参数都是这类型。
3 静态方法参数不可以用类上的泛型。
8 crud
对数据库的增删改查。
9 获取泛型的参数化类型:
通过反射获取获取方法对象调用获取泛型方法可以获取。
十二 类加载器:
1 定义:
1 类加载器是将硬盘上的Class文件处理成字节码文件并加载到内存。
2 Java默认有三个类加载器BootStrap,ExtClassLoader,AppClassLoader。
3 只有BootStrap不是java类他是jvm第一个加载器是c++写的,是加载器的父类。
2 加载器对象器;
1 该类的字节码.getClassLoader()。
2 System类的加载器是BootStrap。
3 三个加载器
1 BootStrap是加载器的父类,被他加载的文件存放在JRE/lib/it.jar内。
2 ExtClassLoader 是BootStrap直接子类,被他加载的文件存放在JRE/lib/ext/*.jar。
3 AppClassLoader是BootStrap的孙子类,被他加载的类存放在ClassPath指定的所有Jar包和目录内。
4 列加载器委托机制:
1 首先当前线程的类加载器去加载线程中的第一个类。
2 如果类A中引用了B类,Java虚拟机将使用记载类A的记载器来记载B类。
3 实际是有最上层的类加载器找路径如没找到会逐级想下加载。到本层还没找到时不会再向下交给本层类加 载器的儿子去加载。
5 自定义类加载器:
1 必须继承ClassLoader类,复写findClass()方法。
2 可以对文件进行加密,都调用自己的类加载器加载类解密。
6 自定义类加载器步骤;
1 编写一个简单的加密程序。
2 编写一个自己的类加载器,可以实现对文件的加密和解密。
3 编写一个调用类加载器的类,在源程序中不能用该类名定义引用变量。
7 练习自定义加载器,加密文件。
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
public class 加密函数 extends ClassLoader {
public static void main(String[] args) throws Exception {
/* String mobiao=args[0];
String mudi=args[1];
String xiangdui=mobiao.substring(mobiao.lastIndexOf('\\')+1);
String bjue=mudi+"\\"+xiangdui;
FileInputStream fi=new FileInputStream(mobiao);
FileOutputStream fo=new FileOutputStream(bjue);
copy(fi,fo);
fi.close();
fo.close();
System.out.println(new Student().toString());*/
Class c= new 加密函数("E:\\eclips\\新建文件夹188\\自定义类加载器\\itcast").loadClass("Student.class");
Date s=(Date) c.newInstance();
System.out.println(s);
}
private String classdir;
@Override
protected java.lang.Class<?> findClass(String name) throws ClassNotFoundException
{
String str=classdir+"\\"+name+".class";
try{
FileInputStream fi=new FileInputStream(classdir);
ByteArrayOutputStream bs=new ByteArrayOutputStream();
copy(fi,bs);
fi.close();
byte[] b=bs.toByteArray();
return defineClass(b, 0,b.length);}
catch(Exception e)
{
e.printStackTrace();
}
return super.findClass(name);
};
public 加密函数() {
super();
// TODO Auto-generated constructor stub
}
public 加密函数(String classdir) {
this.classdir=classdir;
}
public static void copy(InputStream in,OutputStream ou)throws Exception
{
int x=-1;System.out.println("sss");
while((x=in.read())!=-1)
{
ou.write(x^0xff);
}
}
}
import java.util.Date;
public class Student extends Date {
@Override
public String toString() {
return "Student [来了]";
}
}
十三 代理
1 定义:
1 为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能。
2 比如添加运行时间,异常等。
3 采用工厂模式和配置文件来文成。
4 是面向方面的工程,AOP。
5 通过在方法的外面加入代码,或者异常处理内部。
十四 动态代理;
1 虚拟机自己加载出来的字节码。
2 被用于代理类,叫做动态代理。
3 JVM生成的动态代理必须实现一个或多个接口,
所以JVM生成的动态类只能用作具有实现相同接口的目标的代理。
4 当以目标类有实现接口是,需要用CGLIB库生成以个类的子类。
十五 动态生成字节码:
1 使用proxt类的getProxyClass()方法,获取要加载出来的字节码。
2 需要填入要加载字节码实现的接口,和填入要用那个类加载器加载,一般和接口的一样。
3动态代理加载的原理:
1 使用proxy类的getProxyClass()方法,获取要加载出来的字节码。
2 使用字节码文件建立的是Proxy的子类对象。
3 该对象内部有InvocationHandler成员,所以传递构造函数时会复写他的inovke方法。
4 当对象调用方法时回先去调用InvocationHandler内的inovke方法,把该对象,喝掉用的方法名和参数穿进 去。从而可以再invoke方法内加入所需要的代码, 而在InvocationHandler接口内定义了被生成代理类接口 的子类实例对象,所以在每次操作的都是那同一个子类对象,就相当于在collection内定义了以个 实例子类对象。
4 动态加载以个类获所有构造方法,成员方法及参数如下,建立对象调用方法。
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
public class Test {
public static void main(String[] args) {
Class clazzProxy=Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);
String name=clazzProxy.getName();
System.out.println(name);
Constructor[] con=clazzProxy.getConstructors();
Method[] me=clazzProxy.getDeclaredMethods();
for(Constructor c:con){
String name1=c.getName();
StringBuilder sb=new StringBuilder(name1);
Class[] c1=c.getParameterTypes();
sb.append('(');
for(int x=0 ;x<c1.length;x++)
{
if(x!=c1.length-1)
sb.append(c1[x].getName()+",");
else
sb.append(c1[x].getName());
}
sb.append(')');
System.out.println(sb);}
System.out.println("-------------------------------------------");
int x1=0;
for(Method m:me){
String name1=m.getName();
StringBuilder sb=new StringBuilder(name1);
Class[] c1=m.getParameterTypes();
System.out.println(++x1);
sb.append('(');
for(int x=0 ;x<c1.length;x++)
{
if(x!=c1.length-1)
sb.append(c1[x].getName()+",");
else
sb.append(c1[x].getName());
}
sb.append(')');
System.out.println(sb);}
Constructor<Collection> cc=clazzProxy.getConstructor(InvocationHandler.class);
Collection con1=cc.newInstance(new InvocationHandler(){
ArrayList arr=new ArrayList();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(proxy.getClass().getName());
Long start=System.currentTimeMillis();
Object obj=method.invoke(arr, args);
Long end=System.currentTimeMillis();
System.out.println(method.getName()+(end-start));
return obj;
}
} );
con1.add("1");
System.out.println(con1.size());
}
}
5 动态加载第二种形式:Object obj1=Proxy.newProxyInstance
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class MyProxt {
public static void main(String[] args) {
ArrayList<Integer> arr=new ArrayList<>();
Collection con= getProxy(arr);
System.out.println(con.add("s"));
System.out.println(arr);
}
public static <T>T getProxy(final Object obj)
{
Object obj1=Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj2=method.invoke(obj, args);
return obj2;
}
});
return (T)obj1;
}
}
5 注意:
获取的代理类从Object继承过来的方法有三个方法是委托给Propxy类执行的,toString, equals,和 hashcode,其他是自己执行的。
也就是说调用者写方法或取调用invoke其他的不走invoke
十六 让动态类成为目标代理:
1 目标代理就是:代理可以操作不同的类,还可以给定不同的附加代码,
比如不想计算时间了。
2 将要添加的内容定义成接口在生成代理方法上,设为参数用于传递子类实现功能。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class MyProxt {
public static void main(String[] args) {
ArrayList<Integer> arr=new ArrayList<>();
Collection con= getProxy(arr,new MyAdvie());
System.out.println(con.add("s"));
System.out.println(arr);
}
public static <T>T getProxy(final Object obj,final Advice avd)
{
Object obj1=Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
avd.start(method);
Object obj2=method.invoke(obj, args);
avd.end(method);
return obj2;
}
});
return (T)obj1;
}
}
import java.lang.reflect.Method;
public class MyAdvie implements Advice{
long start=0;
@Override
public void start(Method m) {
start=System.currentTimeMillis();
}
@Override
public void end(Method m) {
long end=System.currentTimeMillis();
System.out.println(m.getName()+"运行时间 : "+(end-start)+"秒");
}
import java.lang.reflect.Method;
public interface Advice {
void start(Method m);
void end(Method m);
}
十七 实现AOP框架例题:
package AOP;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeanPactory {
Properties pro=new Properties();
BeanPactory(InputStream in)
{
try {
pro.load(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public Object getBean(String name) throws Exception
{
String className=pro.getProperty(name);
Class clazz=Class.forName(className);
Object bean=clazz.newInstance();
if(bean instanceof ProxyFactor)
{ System.out.println(name);
ProxyFactor pro1= (ProxyFactor) bean;
Advice avd=(Advice) Class.forName(pro.getProperty(name+".adv")).newInstance();
Object obj=Class.forName(pro.getProperty(name+".obj")).newInstance();
pro1.setAvd(avd);
pro1.setObj(obj);
Object proxy=pro1.getProxy();
return proxy;
}
else
return bean;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactor {
private Object obj;//实际要被变成代理的类。
private Advice avd;//要在invoke方法内定义的代码。
public <T>T getProxy( ) {
Object obj1=Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
avd.start(method);
Object obj2=method.invoke(obj, args);
avd.end(method);
return obj2;
}
});
return (T)obj1;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Advice getAvd() {
return avd;
}
public void setAvd(Advice avd) {
this.avd = avd;
}
}
import java.lang.reflect.Method;
public class Advice {
public void start(Method method) {
// TODO Auto-generated method stub
}
public void end(Method method) {
// TODO Auto-generated method stub
}
}
package AOP;
import java.io.InputStream;
public class Test {
public static void main(String[] args) throws Exception {
InputStream in=Test.class.getResourceAsStream("comn.proper");
Object bb=new BeanPactory(in).getBean("xxx");
System.out.println(bb.getClass().getName());
}
}
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------