1. 配置文件的路径
一定要记住用完整的路径,但完整的路径不是硬编码,而是运算出来的。(用方法获得程序的路径+文件和程序的相对路径 )
//InputStream ips=new FileInputStream("config.properties");
//用文件输入流读取该文件内容
//InputStream ips=ReflectTest2.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
//用类加载器获得该文件内容
InputStream ips=ReflectTest2.class.getResourceAsStream("config.properties");
//类加载器的简化形式
2. JavaBean的学习
内省:IntroSpector
JavaBean是一个特殊的java类
获得属性的方法:如果get或set后的字符串的第二个字母是小写的则第一个字母改成小写
3. 对JavaBean的简单内省操作
package cn.itcast.day1;
import java.beans.*;
import java.lang.reflect.*;
public class IntroSpectorTest {
public static void main(String[] args) throws Exception {
ReflectPoit pt1=new ReflectPoit(3,3);//定义一个点对象
String propertyName="x";//设置要操作的字段名
//调用返回字段值的反射方法
Object retVal=getProperty(pt1, propertyName);
System.out.println(retVal);
Object value=7; //字段要设置的值
setProperty(pt1, propertyName, value);//调用设置字段值的反射方法
System.out.println(pt1.getX()); //打印设置完的属性值
}
private static void setProperty(Object pt1, String propertyName,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {//设置字段名的方法
PropertyDescriptor pd1=new PropertyDescriptor(propertyName,pt1.getClass());//通过字段名和类字节码反射出一个字段
Method methodSetX=pd1.getWriteMethod();//获得该字段的写方法
methodSetX.invoke(pt1, value);//写入新的数据
}
private static Object getProperty(Object pt1, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {//返回字段名的方法
PropertyDescriptor pd=new PropertyDescriptor(propertyName,pt1.getClass());//通过字段名反射一个字段
Method methodGetX=pd.getReadMethod();//获得该字段的读方法
Object retVal=methodGetX.invoke(pt1);//读取该字段的值
return retVal;
}
}
4. 对JavaBean的复杂内省操作
private static Object getProperty(Object pt1, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {//返回字段名的方法
/*PropertyDescriptor pd=new PropertyDescriptor(propertyName,pt1.getClass());//通过字段名反射一个字段
Method methodGetX=pd.getReadMethod();//获得该字段的读方法
Object retVal=methodGetX.invoke(pt1);//读取该字段的值
return retVal;*/
Object retVal=null;//定义一个全局变量
BeanInfo beanInfo=Introspector.getBeanInfo(pt1.getClass());//获得类的javabean
PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();//获得所有的javabean属性
for(PropertyDescriptor pd:pds)
{
if (pd.getName().equals(propertyName)) {//遍历所有属性,如果属性名为要求的属性名,则执行操作
Method methodGetX=pd.getReadMethod();//获得该字段的读方法
retVal=methodGetX.invoke(pt1);//针对某一对象,读取该字段的值
break;//退出循环
}
}
return retVal;//返回值
}
5. jdk7新特性
/*Map map={name:xxx,age:18};
BeanUtils.setProperty(map, "name", "x你M");*/
6. 使用BeanUtils工具包
System.out.println(BeanUtils.getProperty(pt1, "x"));//使用beanUtils获得字段x的值
BeanUtils.setProperty(pt1, "x", 9);//使用beanUtils设置x的值为9
System.out.println(BeanUtils.getProperty(pt1, "x"));//打印新的值
BeanUtils.setProperty(pt1, "birthday.time", "1000");//设置类中对象字段的属性
System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));//获得类中对象字段的属性
/*Map map={name:xxx,age:18};
BeanUtils.setProperty(map, "name", "x你M");*/
PropertyUtils.setProperty(pt1, "x", 9); //使用PropertyUtils(操作的类型应该和字段的类型一致)
System.out.println(PropertyUtils.getProperty(pt1, "x"));
7. 了解和入门注解的应用
@SuppressWarings(“deprecation”)用于取消某个编译器的警告
@Deprecated 声明源代码为过期代码
@Override确定下面的方法是否是重写
8. 注解的定义与反射调用
自定义注解:
package cn.itcast.day2;
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 ItcastAnotation {
}
调用注解并用反射判断注解是否存在:
package cn.itcast.day2;
@ItcastAnotation
public class AnnotationTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
if(AnnotationTest.class.isAnnotationPresent(ItcastAnotation.class))
{
ItcastAnotation anotation=(ItcastAnotation)AnnotationTest.class.getAnnotation(ItcastAnotation.class);
System.out.println(anotation);
}
}
@Deprecated
public static void sayHello()
{
System.out.println("hi,传智播客");
}
}
9. 为注解添加属性
package cn.itcast.day2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import cn.itcast.day1.EnumTest;;
//元注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface ItcastAnotation {
String color() default "blue";
String value() ;
int []arrayAttr() default {1};
EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
MetaAnnotation annotationAttr() default @MetaAnnotation("1hm");
}
10.体验泛型
package cn.itcast.day2;
import java.util.*;
public class GenericTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
ArrayList<Integer> collection3=new ArrayList<Integer>();//定义一个泛型集合
//collection3.add("abc");
collection3.getClass().getMethod("add", Object.class).invoke(collection3, "abc");//用反射给泛型集合赋值
System.out.println(collection3.get(0));//取得泛型集合的值
}
}
上述代码证明,泛型只是给编译器看的,如果跳过编译器可以给泛型集合赋值
11.通过迭代输出HashMap中的值
HashMap<String,Integer> maps=new HashMap<String, Integer>();//定义一个泛型HashMap
maps.put("zxx", 28);//向上边集合中添加元素
maps.put("lhm",35);
maps.put("flx", 33);
Set<Map.Entry<String, Integer>> entrySet=maps.entrySet();//把maps的entry读到set中
for (Map.Entry<String, Integer> entry : entrySet) {
System.out.println(entry.getKey()+":"+entry.getValue());//输出set中的值
}
12.定义一个泛型的方法
方法:
public static <T>void swap(T[] a,int i,int j)
{
T temp=a[i];
a[i]=a[j];
a[j]=temp;
}
调用方法:
String [] swap1=new String[]{"aa","bb","cc"};
swap(swap1, 0, 2);
for (String val : swap1) {
System.out.println(val);
}
13.泛型方法练习题
定义一个可以自动转型的方法
方法:
public static <T>T autoConver(Object object)
{
return (T)object;
}
调用:
Object obj="abc1";
String a1=autoConver(obj);
System.out.println(a1);
向数组中填某个数字:
public static <T>void fillArray(T[]a,T obj)
{
for (int i = 0; i < a.length; i++) {
a[i]=obj;
}
}
把集合中的信息复制到数组中:
泛型方法。
泛型类。
泛型类内的静态成员独立定义类型
14.获得方法传入的泛型参数的类型
public static void applyVector(Vector<Date> v1)//定义一个输入参数为泛型集合的方法
{
}
获得输入参数泛型类型的方法:
Method appMethod=GenericTest.class.getMethod("applyVector", Vector.class);//获得该方法
Type[] types=appMethod.getGenericParameterTypes();//获得该方法的泛型参数
ParameterizedType pType=(ParameterizedType)types[0];//用参数类型对象,获得第一个泛型参数
System.out.println(pType.getRawType()); //获得该参数的实际类型
System.out.println(pType.getActualTypeArguments()[0]);//获得该参数的第一个泛型类型
15.类加载器
自己写的类加载器:
1) 需要加密的文件
package cn.itcast.day2;
import java.util.Date;
public class ClassLoaderAttachment extends Date {
public String toString()
{
return "hello,itcast";//重写toString方法
}
}
2) 加密用的方法
public static void cypher(InputStream ips,OutputStream ops ) throws Exception
{
int b=-1;
while ((b=ips.read())!=-1) {
ops.write(b^0xff );//读取字节流,位取反后输出
}
}
3)给主方法在运行里添加两个参数,调用加密的方法,对上边的文件进行加密
public static void main(String[] args) throws Exception {
String srcPath=args[0];//获取第一个参数
String destDir=args[1];//获取第二个参数
FileInputStream fis=new FileInputStream(srcPath);//获得要加密文件的文件输入流
String destFileName=srcPath.substring(srcPath.lastIndexOf("//")+1);//获得文件名
String destPath=destDir+"//"+destFileName;//获得加密后文件的目标地址
FileOutputStream fos=new FileOutputStream(destPath);//建立输出流管道
cypher(fis, fos);//对文件进行加密
fis.close();//关闭流
fos.close();
}
4)编写自己的类加载器
protected Class<?> findClass(String name) throws ClassNotFoundException {
String classFileName=classDir+"//"+name.substring(name.lastIndexOf('.')+1)+".class";//获得加密文件的路径
try {
FileInputStream fis=new FileInputStream(classFileName);//读取加密后的文件
ByteArrayOutputStream bos=new ByteArrayOutputStream();//实例化一个字节数组输出流
cypher(fis, bos);//输入流解密成输出流
fis.close();//关闭输入流
byte[]byes=bos.toByteArray();//把字节数组输出流读取到一个数组中
return defineClass(byes, 0, byes.length);//把字节数组转化成一个类,并返回
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return super.findClass(name);//调用父类的类加载器
}
5)用自己的类加载器加载(主意要删除系统加载器默认加载的文件)
Class clazz=new MyClassLoader("itcastlib").loadClass("cn.itcast.day2.ClassLoaderAttachment");
//输出该类的toString方法
System.out.println(clazz.newInstance().toString());
16.用serverlet显示类加载器
response.setContentType("text/html");
PrintWriter out = response.getWriter();
ClassLoader loader=this.getClass().getClassLoader();
while (loader!=null) {
out.println(loader.getClass().getName()+"<br>");
loader=loader.getParent();
}
out.close();
浏览器结果:
org.apache.catalina.loader.WebappClassLoader
org.apache.catalina.loader.StandardClassLoader
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader