Java高新技术(一)

一、开发工具

01、Eclipse和MyEclipse的关系:03.eclipse工程管理与快捷键配置

(1) MyEclipse是Eclipse的一个插件,不过有的厂商把MyEclipse和Eclipse打包在一起。

02、MyEclipse

(1)编译和运行时所用的版本尽可能相同,高版本的java可以运行低版本的javc。

(2)每个工作间都有自己独立的配置。一个工作间包含多个工程,一个工作间的设置影响这个工作间下的所有工程,而不影响其它工作间。

(3)透视图包含了几个小窗口组成的一个大的工作窗口。透视图是小窗口的集合。

(4)命名规则一般的公司网址倒过来写如cn.itcaats.然后加自己的工作包,如去华为公司面试可写成,cn.itcast.interview.

(5)设置单个工程的javac和java,只要选择那个工程然后右键选择首选项即可。

(6)自定义快捷键和模板可提高编程效率。

(7)导入工程:先复制工程到工作间导入。导入的时候还要注意JDK是否与当前环境兼容。

 二、java5的一些简单新特性

03.java5的静态导入

   也就是把一个类的静态方法或变量导入(import staticjava.lang.Math.*;),便成为当前类的方法而可直接调用。

04.可变参数,就是一个方法的参数个数不固定。

(1)只能出现在参数列表的最后;

(2)…位于变量类型和变量名之间,前后有无空格都可以;

(3)调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数,固定的不属于数组元素。

(4)实现例子:求参数总和

class  VarableParaeter
{
	public static void main(String[] args) 
	{
		System.out.println(add(2,3));
		System.out.println(add(2,3,5,6,7,8));
	}

	public static int add(int x,int… args)
	{
	         int sum=x;
		 for(int i =0;i<args.length;i++)
		 {
		     sum+=args[i];
		 }
		 return sum;
	}
}

05.java5的增强for循环

for(type 变量名:集合变量名){...}

 

注意事项:

(1)迭代变量必须在()中定义。

(2)集合变量可以是数组或实现了iterable接口的集合类

例子:

public static int add(int x,int… args)
	{
	         int sum=x;
		 for(int arg:arfs)
		 {
		     sum+=arg;
		 }
		 return sum;
	}

06.基本数据的自动拆装箱及享元设计模式

(1)例子:

class  AutoBox
{
	public static void main(String[] args) 
	{
	     //自动的把基本数据类型转成Integr并赋给obj,这就是自动装箱。
	     Integr iobj = 3;

	     //自动的Integr类型的iobj转成int类型进行运算,这就是拆箱。
	     System.out.println(iobj + 12);
	}
}

对于int整数要装箱成Integer整数的时候如果大小在一个字节之内(-128~127),一旦包装成一个Integer对象之后就会缓存,下次如果要装箱成一个Integer对象的时候先看缓存里有没有,有的话就从里面直接拿,这样就节省的内存空间,因为比较小的整数使用的频率会很高,如果一出现一个数就创建一个对象,而且这些整数变化不是很大,密度相对高,就没有必要每个都创建对象造成内存浪费,其他类型数据也是这个道理。这是一种设计模式叫享元模式(flyweight)。

(2)享元模式(flyweight):

有很多个小的对象,它们有很多属性相同,把它们变成一个对象,那些不同的属性把它们变成方法的参数称之为外部状态,那些相同的属性称之为这个对象的内部状态。


三、java5的枚举

07.枚举的作用介绍

(1)为什么要有枚举

—— 问题:要定义星期几或性别的变量,该怎么定义?假设用1-7分别表示星期一到星期日,但有人可能会写成int weekday = 0;

 

—— 枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则编译器就会报错。可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。

(2)枚举也是一个类,在里面定义的其它东西必须位于元素列表之后,元素列表之后定义东西元素列表末尾要有;结束。

(3)如果定义构造方法不能是public。

(4)里面的元素是静态的,所以加载一个元素时就执行一次无参的构造方法。如果也调用其它的构造方法则在元素的后面用()起来加入元素即可,如 元素(参数) —> SUN(1,2)

(5)如果一个元素后面有一个{}就表示这是一个子类。

(6)枚举可得一个成员时,就可以作为一种单例的实现方式。

08.用普通类模拟枚举的实现原理

09.java5的枚举的基本应用,如下例子

package cn.itcast.day1;
public class EnumTest {
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		UeekDay ueekDay2 = UeekDay.FRI;
		System.out.println(ueekDay2);
		//获取自己的名字
		System.out.println(ueekDay2.name());
		//自己的排行第几
		System.out.println(ueekDay2.ordinal());
		//将传过来的字符串变成一个对应枚举UeekDay的元素
		System.out.println(UeekDay.valueOf("SUN".toString()));
		//把元素当成一个数组,获取其长度
		System.out.println(UeekDay.values().length);
	}
	public enum UeekDay{
	        //这是一个子类并调用带一个参数的构造函数
		RED(30){

			@Override
			public Trafficlamp nextLamp() {
				// TODO Auto-generated method stub
				return GREEN;
			}
			
		},GREEN(45){

			@Override
			public Trafficlamp nextLamp() {
				// TODO Auto-generated method stub
				return YELLOW;
			}
			
		},YELLOW(5){

			@Override
			public Trafficlamp nextLamp() {
				// TODO Auto-generated method stub
				return RED;
			}
			
		};
		public abstract Trafficlamp nextLamp();
	        private int time;
	        private Trafficlamp(int time){this.time = time;}	    
	
	}
}

四、反射的深入讲解

10.透彻分析反射的基础_Class类

(1)Java程序中的各个Java类属于同一类事物,描述这类囊括的Java类名就是Class。

(2)Class的实例对象是一份内存里的字节码。Class chs1 = Date.class//字节码1;

(3)创建Class时得到一份类的字节码的方式,做反射的时候主要用第三种方法,因为写源程序的时候它不知道类的名字,在运行的时候人家传给一个字符串,这个字符串包含了一个类的名字:

—— 类名.class,例如 System.class

—— 对象.getClass(),例如 new Date().getClass()

——Class.forName("类名"),例如 Class.forName("java.util.Date");

这个方法有两种情况:

     第一种:这份字节码曾经被加载过,已经待在java虚拟机里面了。

     第二种:java虚拟机里面还没有这份字节码,则用类加载器去加载,把加载进来 的字节码放Java虚拟机里面,以后要得到这份字节码就不用加载了。

(4)八个基本数据类型(boolean、byte、char、short、int、long、float 和 double)对象分别有一个对应Class实例对象和关键字 void 也表示为 Class 对象

(5)isPrimitive()判断是否是原始类型(基本类型)的字节码,isArray()判断是否是数组的字节码。

(6)总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int[],void...

(7)例子

package cn.itcast.day1;

public class ReflectTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
        String str1 = "abc";
        //获得String的字节码1
        Class cls1 = str1.getClass();
        //获得String的字节码2
        Class cls2 = String.class;
        Class cls3 = Class.forName("java.lang.String");
        System.out.println(cls1 == cls2);
        System.out.println(cls1 == cls3);
        
        //isPrimitive()判断是否是原始类型(基本类型)的字节码
        System.out.println(cls1.isPrimitive());
        //int 是基本类型
        System.out.println(int.class.isPrimitive());
        System.out.println(int.class==Integer.class);
        System.out.println(int.class==Integer.TYPE);
        System.out.println(int.class.isPrimitive());
        
        //isArray()判断是否是数组的字节码
        System.out.println(int[].class.isArray());
	}

}

11.构造方法的反射应用

(1)得到某个类所有的构造方法(getConstructors()):

Constructor[]constructors=Class.forName("java.lang.String").getConstructors();

 

(2)得到某一个构造方法(getConstructor(参数)):

Constructor constructor =Class.forName("java.lang.String").getConstructor(StingBuffer.class);

Constructor constructor =Class.forName("java.lang.String").getConstructor(类型.class,类型.class...);

 

(3) 创建构造函数

通常方式:Stringstr=new String(new StringBuffer("abc"));

反射方式: Stringstr=(String)constructor.newlnstance(new StringBffer("abc"));

         调用获得的方法时要用到上面相同类型的实例对象。

12.成员变量的反射

Field创建一个实例时实例不是对象身上的值,而是类上,要用它去取某个对象对应的值

13.成员方法的反射

(1)通常方式:System.out.printkn(str.charAt(1));

(2)反射方式:System.out.println(charAt.invoke(str,1));

  如果传递给Method对象的invoke()方法的第一个参数为null,说明该Method对象对应的是一个静态方法!

13. 数组的反射应用

(1)具有相同维数类型的数组属于同一类型,即具有相同的Class实例对象。

(2)代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class、

(3)基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用

     非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用。

(4)不用通过数组中的元素知道数组的类型,但可以知道单个元素所对应的类型,如

    Object[] a = new Object["a",1];

    a[].getClass().getName();

14.ArrayList_HashSet的比较及Hashcode分析

(1)ArrayList:

—— 是一种先后按顺序存储变量引用的一种集合,不考虑是否重复。

 

(2)Hashet:

—— 存储的时候先根据HashSet算法(不同的内存有不同的HashSet算法)的值判断里面是否有相等的数据,不的话就不再写入(set集合就是这样的,不过省去了算法)

—— HashSet的算法,把集合分成若干下区域,每一个要存进来的对象算成一个值,根据算得的值存入相应的相应的区域,而当我们要查找某个对象时,我们先算出这个的对象的HashSet的值,看他属于哪个区域,然后在那个区域中查找是否存在相等对象,这个性能就大大的提高了。

—— 要想你的对象有这样值的对象,前提是你的数据必须存入HashSet这样的集合中,如果其它集合因为没有HashSet这样的结构,所以没有任何价值。

(3)当一个对象被存储进HashSet集合中以后,就不要修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回 找不到对象的结果,这也会无法从HashSet集合中单独删除当前对象,从而造成内存泄露。

(4) 例子:

package cn.itcast.day1;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;

public class ReflectTest1 {
	public static void main(String[] args) throws Exception{
        String str1 = "abc";
        
		Collection collections = new HashSet();
		ReflectPoint p1 = new ReflectPoint(3, 3);
		ReflectPoint p2 = new ReflectPoint(5, 5);
		ReflectPoint p3 = new ReflectPoint(3, 3);
		collections.add(p1);
		collections.add(p2);
		collections.add(p3);
		collections.add(p1);

		System.out.println("集合大小:"+collections.size());
      
        ReflectPoint pt1 = new ReflectPoint(3, 5);
        Field fieldy = pt1.getClass().getField("y");
        //fieldy不是对象身上的值,而是类上,要用它去取某个对象对应的值.get()获取的可见的值
        System.out.println(fieldy.get(pt1));
        
        //x是private的,要用getDeclaredField()获取不可见的值
        Field fieldx = pt1.getClass().getDeclaredField("x");
        //暴力反射(强制访问)
        fieldx.setAccessible(true);
        System.out.println(fieldx.get(pt1));
        
        changeStringValue(pt1);
        System.out.println(pt1);
        
        //str1.charAt();
        Method methodCharAt = String.class.getMethod("charAt", int.class);
        System.out.println(methodCharAt.invoke(str1, 1));
	    
//        TestArguments.main(new String[]{"wgfregh","wfewgrewfg"});
        String startingClassName = args[0];
	    Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
/*	    jdk 1.5为了兼容1.4版本String[]相当于Object[],人家收到一个Object[]数组以后不会把它当作一个参数,
	          人家会把数组这一包东西打开,打开的东西每一个元素当作一个参数,所以出现参数不匹配。
	    mainMethod.invoke(null,new String[]{"111","222","333"});
*/
//(解决方案1)传进一个装Object[]里面的一个元素是String[],当自动拆箱出来后每个元素是一个参数,String[]就当作一个参数传递。	    
	    mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
/*(解决方案2)在前面声明这是一个Object类型的一个元素
	    mainMethod.invoke(null, (Object)new String[]{"111","222","333"});
*/	}

	private static void changeStringValue(Object obj)throws Exception {
		//创建一个存放变量字节码的数组
		Field[] fields = obj.getClass().getFields();
		//迭代所有变量的对应字节码
		for(Field field : fields){
/*			判断变量的对应字节码是否是String类型,不用
			if(field.getType().equals(String.class))
			因为是对同一份字节码的比较,应该用==而不用equals
*/		    if(field.getType()==String.class){
		    	//获取对应的字节码变量的值
		    	String oldValue = (String)field.get(obj);
		    	//调换值
		    	String newValue = oldValue.replace('b', 'a');
		    	//对field对象进行设值
		    	field.set(obj,newValue);
		    }
		}
	}
}

class TestArguments{
	public static void main(String[] args){
		for(String arg : args){
			System.out.println(arg);
		}
	}
}
class ReflectPoint {
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ReflectPoint other = (ReflectPoint) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}
	private int x;
	public int y;
	public String str1 = "ball";
	public String str2 = "basketball";
	public String str3 = "itcast";
	
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	@Override
	//覆盖方法
	public String toString() {
		// TODO Auto-generated method stub
		return str1 +":"+str2+":"+str3;
	} 	
}

15.由内省引出JavaBean的讲解

(1)IntroSpector(查找)--->JavaBean(方法是由get(没有参数传递)或set打头,并都是public)-->特殊的Java类。

(2)如果一个类中有get或set的方法打头也可以把它当成JavaBean来操作。

(3)一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当JavaBean用肯定给我们带来一些额外的好处。

(4)JavaBean的好处:

—— 在Java EE开发中,经常要使用到JavaBean,很多环境就要求按JavaBean方式进行操作,别人都 要求那么做,那我们就没有选择的余地。

—— JDK中担供了对JavaBean进行操作的一些API,这套API就称为内省。

(5)属性的特点:

—— 去掉get或set后的名称改成小写-->如果第二字母小的,则把第一个字母变成小的,同理则变成大-->属性名

(6)综合例子

——ReflectPoint.java文件

package cn.itcast.day1.setter;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class IntrospectorTest {

	public static void main(String[] args) throws Exception {
		javabean2();
	}
	
	//用Myeclipse自动生成getter和setter方法
	public static void javabean2() throws Exception{
		  ReflectPoint pt1 =new ReflectPoint(3,5);
	        String propertyName = "x";

			Object retVal = getProperty(pt1, propertyName); 
	        System.out.println(retVal);
	        
	        Object value = 7;   
			setProperty(pt1, propertyName, value);
			Object retVal2 = getProperty(pt1, propertyName); 
	        System.out.println(retVal2);
	}
private static void setProperty(ReflectPoint pt1, String propertyName, Object value)
		throws IntrospectionException, IllegalAccessException,
		InvocationTargetException {
/*  PropertyDescriptor是属性描述符的类,它的构造函数接收两个参数是(属性名,类(表示要打哪个类当作JavaBean来用))
          得到对应类的属性pd*/
	PropertyDescriptor pd =new PropertyDescriptor(propertyName , pt1.getClass());
//	得到类中getter方法
	Method methodSetX = pd.getWriteMethod();
//	在pt1上调用这个方法,并传递参数
	methodSetX.invoke(pt1,value);
}
private static Object getProperty(ReflectPoint pt1, String propertyName)
		throws IntrospectionException, IllegalAccessException,
		InvocationTargetException {
	PropertyDescriptor pd =new PropertyDescriptor(propertyName , pt1.getClass());
	Method methodGetX = pd.getReadMethod();
//	在pt1上调用这个方法,并且get不用传递参数,得到一个反回值
	Object retVal = methodGetX.invoke(pt1);
	return retVal;
}
}


package cn.itcast.day1.setter;

public class ReflectPoint {
		private int x;
		public int y;
		public ReflectPoint(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}
		public int getX() {
			return x;
		}
		public void setX(int x) {
			this.x = x;
		}
		public int getY() {
			return y;
		}
		public void setY(int y) {
			this.y = y;
		}
	}

16. 使用BeanUtils工具包操作JavaBean

—— BeanUtils数据传递是以字符串传递。






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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值