java自学笔记之java高新技术
2014-01-21 17:12
232 查看
Java高新技术:
import static java.lang.math.*; //静态导入overload:重载
override:重写
可变参数: ...;当成数组。
高级for循环:只适合取数据。
自动装箱拆箱:Integer对象在-128 ~ 127之间的对象是相等的。这是一种设计模式,享元模式,flyweight节约内存
枚举:
public enum WeekDay{SUN(0),MON(1),TUE(2),WED(3),THT(4),FRI(5),SAT(6)
private WeekDay() {};
private String value;
public WeekDay(value){
this.value = value;
}
public String getValue()
{
return this.value;
}
private WeekDay(int day) {};
}
public enum TrafficLamp{
RED(30){
public TrafficLamp nextLamp()
return GREEN;
}
GREEN(45){
public TrafficLamp nextLamp()
return YELLEO;
}
RED(15){
public TrafficLamp nextLamp()
return RED;
}
public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp(int time){
this.time = time;
}
}
枚举如果只有一个值就相当于用单台设计模式定义出一个类。
反射的基石 Class类
获得字节码:类名。class ;对象。getClass ; Class。forName("");//获得构造方法:
Constructor[] constructors = Class.forName("").getConstructors();
或获取一个 Constructor constructor = Class.forName("").getConstruector(xx.class);
//创建实例对象:
String str = (String) constructor.newInstance(new xx(""));
//跳过构造方法直接获取实例对象:(用缓存保存)
Stirng str = (String)Class.forName("").newInstance();
//获取字段
Field [] fields = obj.getClass().getFields();
for(Field field : fields)
{
if(field.getType() == String.class())
{
String oldValue = (String)field.get(obj);
String newValue = (String)field.replace('','');
field.set(obj,newValue);
}
}
//获取成员方法
Method method = String.class.getMethod("方法名",参数字节码);
method.invoke(对象,参数);
//反射执行类中的main方法
mainMethod.invok(null,new Object[]{new String[]{"xxx"}});
//数组的反射:
hashCode():哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。hashCode方法实际上返回的就是对象存储的物理地址.
反射实现框架功能:
以前开发的框架可以通过反射调用现在开发的程序。
建一个properties文件。然后读取这个文件的键值对。
InputStream is = new FileInputStream("config.properties");
//properties的加载路径变化
//InputStream is = ReflectTest.class.getClassLoader().getResourceAsStream("com/youxiang/config.properties")
//或者是InputStream is = ReflectTest.class.getResourceAsStream("config.properties");
Properties prop = new Properties();
prop.load(is);
prop.close();
String className = prop.getProperties("className");
Collection collections = (Collection)Class.forName(className);
内省IntorSpector:
主要是对Java Bean属性、方法等的一种处理方法//PropertyDescriptor来设置和获取值
ReflectPoint rp = new ReflectPoint(3,5);
String propertyName = "x";
PropertyDescriptor pd = new PropertyDescriptor(propertyName,rp.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(rp);
//BeanInfo 的 Introspector 来设置和获取值
BeanInfo. beanInfo = Introspector.getBeanInfo(Person.class);
PropertyDescriptors [] pds = beanInfo.getPropertyDescriptors();
for(PropertyDescriptor pd : psd)
{
if(pd.getName().equals(propertyName))
{
Method methodGetX = pd.getReadMethod();
retVal = nethodGetX.invoke(pt);
break;
}
}
//Beanutils工具包来设置和获取值:
需要先将jar包下载导入到工程
BeanUtils.getProperty(rp,"x").getClass().getName();
BeanUtils.setProperty(rp,"x","9");
//操作map
Mao map = new HashMao();
map.put("name","youxiang");
BeanUtils.populate(bean,map);
BeanUtils默认只能转换八种默认数据类型,
如Date类型就不能转换set值。需要注册一个日期转换器,实现Coverter()接口
ConvertUtils.register(new Converter(){
public Object convert(Class type,Object value){
if (value == null) {
return null;
}
if (!(vlaue instanceof String)) {
throw new ConversionException("只支持String类型");
}
String str = (String) value;
if (str.trim().equals("")) {
return null;
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
return df.parse(str);
}
},Date.class);
//java7的新特性
Map map={name:"zxx",age:18};
BeanUtils.setProperty(map,"name","1=hm");
注解:annotation
相当于一种标记,Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。@Deprecated:表示子类要重写(override)父类的对应方法
@Override:表示方法是不建议被使用的。
@SuppressWarnings:表示抑制警告
自定义注解:
Java中提供了四种元注解,专门负责注解其他的注解@Retention元注解,表示需要在什么级别保存该注释信息(生命周期)。可选的RetentionPoicy参数包括:
RetentionPolicy.SOURCE: 停留在java源文件,编译器被丢掉
RetentionPolicy.CLASS:停留在class文件中,但会被VM丢弃(默认)
RetentionPolicy.RUNTIME:内存中的字节码,VM将在运行时也保留注解,因此可以通过反射机制读取注解的信息
@Target元注解,默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括
ElementType.CONSTRUCTOR: 构造器声明
ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
ElementType.LOCAL_VARIABLE: 局部变量声明
ElementType.METHOD: 方法声明
ElementType.PACKAGE: 包声明
ElementType.PARAMETER: 参数声明
ElementType.TYPE: 类、接口(包括注解类型)或enum声明
@Documented将注解包含在JavaDoc中
@Inheried允许子类继承父类中的注解
泛型:
是提供給javac编译器使用的,用于限定输入的类型。用泛型时,如果两边都是用到泛型,两边必须要一样的泛型。
Map<Integer,String> map = new HashMap<Integer,String>();
map.put(1, "aa");
map.put(2, "bb");
map.put(3, "cc");
Set<Map.Entry<Integer, String>> set1 = map.entrySet();
for(Map.Entry<Integer, String> entry: set1){
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+".."+value);
}
1,整个ArrayList<E>称为泛型类型
2,ArrayList<E>中的E称为类型变量或类型参数3,整个ArrayList<Integer>称为参数化的类型
4,ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数。
5,ArrayList<Integer>中的<>念着typeof
6,ArrayList称为原始类型
参数化类型和原始类型是具有兼容性的:Vector<String> c = new Vector();
原始类型可以引用一个参数化类型的对象:Vector c = new Vector<String>();
参数化类型不考虑继承关系。错误:Vector<String> v = new Vector<Object>();
编译器不允许创建参数化类型数组。错误:Vector <Integer> v[] = new Vector<Integer>[20];
通配符:'?'只能对变量进行引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
向上限定:?extends Number:?或者?的子类;
向下限定:?super Integer :?的父类或者?。
自定泛型:
在方法上定义一个泛型,格式是在返回值前加上“<泛型变量名称>”;public static <T> void doxx(T t);只有引用类型才能作为泛型方法的实际参数,如String Integer等,基本数据类型如int等不能
泛型也可以使用在异常中。
类型推断:定义的泛型方法代表返回两者的最大公约数:
静态方法使用的泛型只能是定义在方法上的。
//编写一个泛型方法,实现指定位置上的数组元素的交换。
public <T> void swap(T arr[],int pos1,int pos2){
T temp = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = temp;
}
//编写一个泛型方法,接受一个任意数组,颠倒数组输出。
public <T>void reverse(T arr[]){
int start = 0;
int end = arr.length-1;
while(true){
if (start>=end) {
break
}
T temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
如何通过反射获得泛型的参数化类型:
Method generMethod = GenericTest.class.getMethod("genericTypeApp", ArrayList.class);
Type[] genericType = generMethod.getGenericParameterTypes();
System.out.println(genericType[0]);
System.out.println(generMethod.getParameterTypes()[0]);
public static void genericTypeApp(ArrayList<String> a){}
类加载器:ClassLoader
类加载器负责把类加载到Java虚拟机(JVM)中。指定类的名称,类加载器就会定位这个类的定义,每一个Java类必须由类加载器加载。启动JVM的时候,可以使用三个类加载器:引导(bootstrap)类加载器(第一个加载器它不是java类)、扩展(extensions)类加载器、应用程序(application)类加载器。
得到类加载名称:类.class.getClassLoader().getClass().getName();
当处理类加载器时,父委托模式是一个需要理解的关键概念。它规定:类加载器在加载自己的类之前,可以委托先加载父类。
父类加载器可以是客户化的类加载器或者引导类加载器。但是有一点很重要,类加载器只能委托自己的父类加载器,而不能是子类加载器(只能向上不能向下)。
全盘负责 委托机制
classloader 加载类用的是全盘负责委托机制。全盘负责:即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的其它Class通常也由这个classloader负责载入。
委托机制:先让parent(父)类加载器寻找,只有在parent找不到的时候才从自己的类路径中去寻找。
类加载还采用了cache机制:如果cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么修改了Class但是必须重新启动JVM才能生效,并且类只加载一次的原因。
自定义类加载器:
1、 自定义的类加载器必须继承ClassLoader。2、 ClassLoader中有loadClass()和findclass()两个方法,loadClass()方法实现了委托机制,findClass()方法辅负责自己加载类,因此我们只需重写findClass()方法
3、 defineClass()方法。通过findClass()得到class文件中的二进制数据后,用findClass()方法将其转换为字节码。
代理和动态代理:
动态代理: JVM可以在运行期动态生成类的字节码,这种动态生成往往被用作代理类,即为动态代理.jvm生成的动态类必须实现一个或多个接口,所以,jvm生成的动态类只能用作具有相同接口的目标类的代理。
其实动态代理机制最核心的就是InvocationHandler(调用处理器)这个接口InvocationHandler 是代理实例的调用处理程序 实现的接口。
代理对象:代理类所生成的对象。
目标对象:代理类所代理的那个类生成的对象。
相关文章推荐
- 黑马程序员 Java自学总结十九 Java高新技术第二天
- Java SE 自学笔记1
- 黑马程序员--【强哥笔记】系列之Java高新技术笔记之JavaBean内省(第4天)
- 大龄屌丝自学笔记--Java零基础到菜鸟--015
- 大龄屌丝自学笔记--Java零基础到菜鸟--013
- 黑马程序员--【强哥笔记】系列之Java高新技术笔记之泛型(第6天)...
- 大龄屌丝自学笔记--Java零基础到菜鸟--036
- java自学笔记之抽象类,接口,对象的多态性,instanceof关键字
- (JAVA自学笔记)I/O流操作
- 传智播客Java自学笔记第19天(待编辑)
- 大龄屌丝自学笔记--Java零基础到菜鸟--023
- (JAVA自学笔记)静态导入
- 黑马程序员---Java高新技术学习笔记(中篇)
- 自学Java系列 笔记1 java的基本语法3
- JavaSwing自学笔记之_JScrollPane(设置注意点)
- java自学笔记之面试题银行业务调度系统
- 测试工程师修炼笔记_Java自学推荐
- Java自学笔记
- 学习笔记15—Java高新技术3
- Java培训笔记22--自学异常类