JAVA学习 -08


java高新技术


eclipse的使用技巧

javaee

ide -->itegrity debelopoment environment  集成开发环境

jms

jmx

jndi


preferences 喜好  首选项

switch workspace 切换工作间

perspective 透视图

面试技巧  包名   编码规范

debug  watch  可以看变量的值(老师的普通话啊!!!)

透视图是视图的集合

如何设置单个工程的javac和java

工程右键--preference--java--compiler

模版代码设置
preferences--editor--Templates 


静态导入(1.5新特性)

import语句可以导入一个类或或某个包中的所有类

import static语句导入一个类中的某个静态方法或所有静态方法

可变参数(1.5新特性)
方法参数个数不固定

增强for循环(1.5新特性)
语法for(Type obj:集合变量名){。。。}

注意事项:
  迭代变量必须在()中定义!
  集合变量可以是数组或实现了Iterable接口的集合类


基本数据类型的自动装箱与拆箱

Integer iObj = 3;  //1.4之前是报错的
装箱:自动将一个基本类型装箱成一个
Integer类型再赋给iObj变量

System.out.println(iObj+12);
拆箱:将引用类型转换成基本类型再进行假发运算

对于基本数据类型的整数,如果数据在一个字节(-128  -  127)之内,装箱后缓存到池中,以反复使用。

享元模式:如果很多很小的对象,他们有很多属性相同,就可以将其编程一个对象,不同的属性变成方法的参数,称之为外部状态,相同的属性称之为内部状态
节省资源flyweight


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


package com.sun.day1;

public abstract class WeekDay {

 private WeekDay(){}
 
 public final static WeekDay SUN = new WeekDay(){

  @Override
  public WeekDay nextDay() {
   // TODO Auto-generated method stub
   return MON;
  }
  
 };
 public final static WeekDay MON = new WeekDay(){

  @Override
  public WeekDay nextDay() {
   // TODO Auto-generated method stub
   return SUN;
  }};

 /*public WeekDay nextDay(){
  if(this == SUN)
   return MON;
  else
   return SUN;
 }*/
 
 public abstract WeekDay nextDay();
 
 public String toString(){
  return this == SUN?"Sunday":"Monday";
 }
}

将大量的if else语句转移成了一个个独立的类


枚举的基本应用:
  枚举是一种特殊的类,其中的每个元素都是该类的一个实例对象,例如可以调用WeekDay.SUN.gteClass().getName和WeekDay.class.getName()

1.元素列表必须在所有成分之前
2.元素列表后要是有其他部分 必须加分号
3.构造方法必须为private
4.枚举元素后加上括号指定其调用的构造方法

如果枚举只有一个成员时,就可以作为一个单例的实现方式。

 

反射(1.2不是1.5新特性)
反射的基石  Class类

Class--->代表这类实物的Java类名就是Class

Java类用于描述一类事务的共性,该类实物有什么属性,没有什么属性,至于这个属性的值是什么,则室友这个类的实例对象来确定的,不太能够的类实例对象有不同的属性值。Java程序中的各个Java类,他们是否属于同一类事务,是不是可以用一个类来描述这类事务呢?这个类的名字就是Class,要注意与小写class关键字的区别。Class类描述了哪些方面的信息呢?类的名字,类的访问属性,类所属于的包名,字段名称的列表,方法名称的列表,等等。

得到实例对象的字节码(Class类型)
类名.class,例如,System.class
对象.getClass(),例如,new Date().getClass()
Class.forName("类名"),例如,Class.forName("java.util.Date")

Class.froName("类名") 有两种情况,一种是在内存中找到已存在的字节码,另一种是创建新的对象的字节码


九个预定义Class对象
boolean,byte,char,short,int,long,float,double(8个基本数据类型)和void

Class c1 = void.class;

参看Class.isPrmitive(是否是原始类型)方法的帮助
int class = Integer.TYPE;
(TYPE所包装的基本数据类型)

判断是否是数组类型的Class实例对象Class.isArray()
总之,只要是在源程序中出现的类型,都有格子的Class实例对象,例如,int,void...


反射

反射就是把Java类中的各种成分映射成相应的java类。
例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示,就像七成是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示Java类的Class类显然要提供一系列的方法,来获取其中的变量,方法,构造方法,修饰符,包等信息。这些信息就是用相应类的实例对象来表示,塔门是Field、Method、Contructor、Package等等。
一个类中的每隔成员都可以用相应的反射API类的一个实例对象来表示。

Constructor类
代表某个类中的一个构造方法
得到某个类的所有的构造方法
  Construstor[] constructors = Class.forName("java.lang.String").getConstructors();

得到某个类中的一个构造方法
Constructor constructor = Class.forName("java.lang.String").getContructor(StringBuffere.class);
获得方法时要用到类型

创建实例对象
通常方式:String str = new String(new StringBuffer("abc"));
反射方法:String str = (String)constructor.newInstance(new StringBuffer(StringBuffer.class));
调用获得的方法时要用到上面相同的实例对象

Class.newInstance();


 
newInstance() 反射调用构造方法创建对象
例子:String obj =(String)Class.forName("java.lang.String").newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
该方法内部的具体代码是调用默认的构造方法,再用构造方法创建类对象。用到了缓存机制来保存默认构造方法的实例对象


反射会导致性能下降

Field类
getFile()方法获取非私有变量
getDeclaredField()方法获取声明的变量
setAccessable(boolean b)暴力访问,设置可否访问私有变量

作业:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的“b”改成“a”。

private static void changeStringValue(Object obj)throws Exception{
  Field[] fields = obj.getClass().getFields();
  for(Field field :fields){
   if(field.getType() == String.class){
    if(!field.isAccessible())
     field.setAccessible(true);
    String strValue = (String)field.get(obj);
    strValue = strValue.replace('b', 'a');
    System.out.println(strValue);
    field.set(obj, strValue);
   }
  }
 }

Method类
代表某个类中的一个成员方法
得到类中的某一个方法
例子:Method charAt = Class.forName("java.lng.String").getMethod("charAt", int.class);
调用方法
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str, 1));

如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢》说明该Method对象对应的是一个静态方法!

jdk1.4和jdk1.5的invoke方法的区别
jdk1.5:public Object invoke(Object, Object...args)
jdk1.4:public Object invoke(Object obj, Object[] args)
即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每隔元素分别对应被调用方法中的一个参数,所以,调用charAt方法的代码也可以用jdk1.4改写为charAt。invoke(“str”, new Object[]{1})形式

用反射方式执行某个类中的main方法
目标:
  写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
问题:
启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args), 通过反射的方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每隔元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照那种语法进行处理呢?jdk1.5可定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用直接传递数组的方式,javac只把它当作jdk1.4的语法进行丽姐,而不把它当作jdk1。5的语法解释,因此会出现参数类型不对的问题。
解决办法
manMethod.invoke(null,new Object[]{new String[]{"xxx"}});
mainMethod.invoke(null,(Object)new String[]{"xxx"});,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会将数组打散成若干个参数了


数组的反射

具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象

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

基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用,非基本类型的一维数组即可以当作Object类型使用,也可以当作Object[]类型使用。

Arrays.asList()方法处理int[]和String[]时的差异

Array工具类用于完成对数组的反射操作

怎么得到数组中的元素类型?
无法判定数组的类型
只能获取数组内的元素 在判断数组内元素的类型

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值