java自学笔记之java高新技术

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 是代理实例的调用处理程序 实现的接口。
代理对象:代理类所生成的对象。
目标对象:代理类所代理的那个类生成的对象。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值