黑马程序员_温习 高新技术一 (个人笔记)摘要(静态导入---可变参数----高级FOR循环---自动装箱(拆箱)----枚举----反射)

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------


摘要(静态导入---可变参数----高级FOR循环---自动装箱(拆箱)----枚举----反射


小体会:高新技术这里,个人感觉挺难的,首先 eclipse 之前没用过

其次和毕老师的教程联系不太多,第一次看的迷迷糊糊的

 直到第二遍才有点感觉, 尤其是反射的原理想了很久才有点明白。


静态导入: import   static java........(可以导入包中的静态方法,实现代码简化书写)


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


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


语法举例:


      |-- import static java.lang.Math.sin;


      |-- import static java.lang.Math
 

                              

自动装箱:把基本数据类型int,自动转换为对象Integer


自动拆箱:把integer自动转为基本数据类型int

Integer num1 = 12;
自动拆箱:
System.out.println(num1 + 12);
基本数据类型的对象缓存:
Integer num1 = 12;
Integer num2 = 12;           这块相等,
System.out.println(num1 == num2);
 
Integer num3 = 129;                这块不相等
Integer num4 = 129;
System.out.println(num3 == num4);
 
Integer num5 = Integer.valueOf(12);
Integer num6 = Integer.valueOf(12)  ;  
System.out.println(num5 == num6);
                                枚举
枚举类的实例对象个数是有限的,就是那些成员,可以在枚举类的构造方法中加入监控语句,看到这几个实例对象被创建出来的过程。
如果想在一个类中编写完各个枚举类和测试调用类,那么可以将枚举类定义成调用类的内部类。
实现抽象的next方法:每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义。增加上表示时间的构造方法
 
枚举只有一个成员时,就可以作为一种单例的实现方式。
讲构造方法枚举时,最好是定义一个带参数的构造方法和一个不带参数的构造方法,问大家默认调用的是哪个构造方法,然后提问想选择带参数的构造方法,该如何做呢?
 
如果枚举元素后面没有大括号对,那是不会生成内部类的。先看有内部类的效果,再看没有内部类的效果,eclipse自动删除原来的内部类。
 
写带有抽象方法的枚举步骤和技巧:
        1. enum TrafficLamp{RED,GREEN,YELLOW}
        2. enum TrafficLamp{RED,GREEN,YELLOW;public abstract next();}
        3.enum TrafficLamp{RED{},GREEN{},YELLOW{};public abstract next();}
        4.填充各个{}中的next方法。
                               反射
 
importjava.lang.reflect.*;
importjava.util.Arrays;
public class ReflectTest {
 
    public static void main(String[] args) throws Exception{
       // TODO Auto-generated method stub
       String str = "hello";
       //获取String类的字节码,三种方法:
       Class cls1= String.class;
       Class cls2= str.getClass();
       Class cls3= Class.forName("java.lang.String");
       System.out.println(cls1==cls2);//true
       System.out.println(cls1==cls3);//true
     
       System.out.println(cls1.isPrimitive());//false
       System.out.println(int.class.isPrimitive());//true
       System.out.println(int[].class.isPrimitive());//false
       System.out.println(int[].class.isArray());//true
       System.out.println(int.class == Integer.class);//flase
       System.out.println(int.class == Integer.TYPE);//true
       //获取构造器并构造对象
     
       //获取对应类的构造方法,根据参数的不同来指定不同的构造方法
       Constructor<String> constr = String.class.getConstructor(StringBuffer.class);
       String string =constr.newInstance(new StringBuffer("abc"));
       //如果需要调用无参构造方法,可以使用Class.newInstance();
       System.out.println(string);
 
       //反射:获取对象的成员变量
     
       ReflectPoint r = new ReflectPoint(3,5);
       //getDeclaredField取出声明过的变量,包括public和private
       Field fy = r.getClass().getDeclaredField("y");
       System.out.println(fy.get(r));
       Field fx = r.getClass().getDeclaredField("x");
       fx.setAccessible(true);//暴力反射,将private成员设置成可见,才能被get获取
       System.out.println(fx.get(r));
       changeStringValue(r);
       System.out.println(r);
     
       //反射:获取对象的成员方法
     
       Method sumMethod = r.getClass().getMethod("getSum",int.class,int.class);
       //调用r对象的getSum方法,并且如果该方法是static的,参数可以是null
       //sumMethod.invoke(null,6,7);
       //参数类型不确定的情况,可以使用Object数组:sumMethod.invoke(r,new Object[]{每个参数的值});
       int sum = (Integer)sumMethod.invoke(r,6,7); 
       System.out.println(sum);
      -
       //反射:调用另一个类的main函数(类的静态方法)
       //即:对接收数组参数的成员方法进行反射
     
       //需要先设置运行对话框里先设置program argument的值(完整类名)
       String startClassName = args[0];
       Method mainMethod = Class.forName(startClassName).getMethod(
              "main", String[].class);
     
       //当String数组传入时会被拆包,因此需要使用new Object[]{String[]}
       //或者(Object)强制转换,阻止对该数组的拆包。
       System.out.println(mainMethod.invoke(null,
              new Object[]{new String[]{"111","222","333"}}));
     
     
       System.out.println(a1.getClass().getSuperclass().getName());
       System.out.println(a4.getClass().getSuperclass().getName());
     
       Object obj1 =a1;
       Object obj2 =a4;
       //Object[] obj3 = a1;//编译失败,因为al里装的是int元而不是Object对象
       Object[] obj4 = a3;
       Object[] obj5 = a4;
       //Arrays.asList(Object[] obj),而int是元数组而不是对象数组,因此不符合参数条件
       System.out.println(Arrays.asList(a1));//hash值
       System.out.println(Arrays.asList(a4));//元素值
     
 
       //数组的反射
     
       //当有一个Object数组,元素值类型不一,就需要用到反射来取元素及元素类型
       printArray(a4);
    }
  
    public static void printArray(Object obj){
       Class class_ex = obj.getClass();
       if(class_ex.isArray()) {
           int len = Array.getLength(obj);
           for (int i = 0; i < len; i++) {
              System.out.println(Array.get(obj,i));
           }
       } else {
           System.out.println(obj);
       }
    }
  
    public static void changeStringValue(Object obj)throws Exception{
       Field[] fields = obj.getClass().getFields();
      
       for (Field field : fields) {
           if(field.getType()==(String.class)) {
              String newstr = field.get(obj).toString().replaceAll("b","a");
            
              //将obj对象的field字段设置成newstr
              field.set(obj,newstr);
           }
       }
    }
 
}
 
class TestArgument{
    public static void main(String[] args){
       for (String string : args) {
           System.out.println(string);
       }
    }
}
public class ReflectPoint {
    private int x;
    public int y;
    public String str1="ball";
    public String str2="baseball";
    public String str3="itcast";
  
    publicReflectPoint(int x, int y) {
       this.x = x;
       this.y = y;
    }
  
    @Override
    public String toString(){
       return "x= "+x+" ;y= "+y+"\n"+"str1= "+str1+"" +
              " ;str2= "+str2+" ;str3= "+str3;
    }
  
    @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;
    }
 
    public int getSum(int a,int b){
       return a+b;
    }
}
HashCode与内存泄露
import java.util.*;
public class ReflectTest2 {
    public static void main(String[] args){
       Collection coll = new HashSet();
     
       ReflectPoint r1 = new ReflectPoint(3,3);
       ReflectPoint r2 = new ReflectPoint(5,5);
       ReflectPoint r3 = new ReflectPoint(3,3);
     
       coll.add(r1);
       coll.add(r2);
       coll.add(r3);//覆盖了HashCode方法和equals方法,因此视为与r1相同元素
       coll.add(r1);
       System.out.println(coll.size());//2
     
       r1.y=2;
       coll.remove(r1);
       System.out.println(coll.size());//2
       //原因是:当涉及到HashCode值的字段发生了改变,那么再去搜索就找不到原来
       //对应的HashCode的元素了,但是程序员察觉不到,就造成了内存泄露。
    }
}


import java.io.*;
import java.util.*;
/  *利用反射技术使用运行时的类,反射技术开发框架原理 *  /
public class ReflectTest2 {
       public static void main(String[] args) throws Exception{
            
              //一定要记住用完整的路径,但完整的路径不是硬编码。而是通过运算得出来的。
              //InputStream in = new FileInputStream("config.properties");
            
              //使用类加载器的方式管理配置和资源文件。
              //InputStream in = ReflectTest2.class.getClassLoader().getResourceAsStream("cn\\itcast\\day2\\config.properties");
            
              //相对主类所在的包的相对路径
              InputStream in = ReflectTest2.class.getResourceAsStream("config.properties");
              //如果是放在cn.itcast.resource包里,则就要使用该包的相对路径"resourse\\config.properties"
              //因此,资源文件一般放在eclipse的src目录或者子目录下。
            
              Properties props = new Properties();
              props.load(in);
              String className = props.getProperty("className");
 
              //要将泛型实例指定为Collection对象
              Collection coll = (Collection)Class.forName(className).newInstance();
              coll.add("java01");
              coll.add("java02");
              coll.add("java03");
              coll.add("java01");
            
              System.out.println(coll.toString());
       }
}
      JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
       如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,大家觉得这些方法的名称叫什么好呢?JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,至于你把它存到哪个变量上,用管吗?如果方法名为getId,中文意思即为获取id,至于你从哪个变量上取,用管吗?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
 
import java.beans.PropertyDescriptor;
import java.lang.reflect.*;;
/  *内省的简单应用方式*  /
public class IntroSpectorTest1 {
       public static void main(String[] args) throws Exception{         
              ReflectPoint rp = new ReflectPoint(3,5);
            
              //利用给定的属性名对getter和setter进行调用
              //利用PropertyDescriptor设置属性描述,构造方法参数为属性名及所在类
              String prop = "x";
              PropertyDescriptor pd = new PropertyDescriptor(prop,rp.getClass());
            
              //以下get/setProperty方法利用Refactor进行重构,导出方法-->Extract methood
              Object retValue = getProperty(rp, pd);
              System.out.println(retValue);
            
              Object setValue = 7;
              setProperty(rp, pd, setValue);
              System.out.println(getProperty(rp,pd));
       }
     
       / *PropertyDescriptor的getReadMethod以及getWriteMethod方法返回一个Method类型对象
       / *需要用invoke方法进行对应setter getter方法的调用
        ** /
       public static void setProperty(Object rp, PropertyDescriptor pd,
                     Object setValue) throws IllegalAccessException,
                     InvocationTargetException {
            
              Method setMethod  = pd.getWriteMethod();
              setMethod.invoke(rp, setValue);
       }
 
       public static Object getProperty(Object rp, PropertyDescriptor pd)
                     throws IllegalAccessException, InvocationTargetException {
            
              Method getMethod  = pd.getReadMethod();
              Object retValue = getMethod.invoke(rp);
              return retValue;
       }
 
}
    / *使用BeanInfo方法
     *
     * * /
    public static Object getProperty(Object rp, String prop)
throws IllegalAccessException, InvocationTargetException, IntrospectionException {
         
       BeanInfo beanInfo = Introspector.getBeanInfo(rp.getClass());
       PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
       Object refValue = null;;
       for (PropertyDescriptor pd_x : pds) {
           if (pd_x.getName().equals(prop)) {
              Method getMethod = pd_x.getReadMethod();
              refValue = getMethod.invoke(rp);
              break;
           }
       }
       return refValue;
    }


      在前面内省例子的基础上,用BeanUtils类先get原来设置好的属性,再将其set为一个新值。
      get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。
       用PropertyUtils类先get原来设置好的属性,再将其set为一个新值。
     去掉JavaBean(ReflectPoint)的public修饰符时,BeanUtils工具包访问javabean属性时出现的问题。
 
/ *使用BeanUtils方法(自己下载包:beanutils和logging):
        * System.out.println(BeanUtils.getProperty(rp,prop));
        * BeanUtils.setProperty(rp,prop,"9");  //以String类型进行设置
        * System.out.println(BeanUtils.getProperty(rp,prop));
        *
        * 当存在对象类型的属性:private Date birthday = new Date();
        * 则需要用属性链进行设置,用属性链进行查看
        * BeanUtils.setProperty(rp,"birthday.time","12000");
        * System.out.println(BeanUtils.getProperty(rp,"birthday.time"));
        *
        * BeanUtils是以字符串String类型对属性值进行操作,PropertyUtils是以属性值本身类型进行操作
        * PropertyUtils.setProperty(rp,prop,9);
        * System.out.println(BeanUtils.getProperty(rp,prop));
* //返回Integer值
        *
        * java7的新特性:Map定义
        * Map map = {name:"yun",age:20};
        * 通过describe和populate两个方法,在bean对象和map对象时间进行转换。
        * * /


 
      定义一个最简单的注解:public @interface MyAnnotation {}
      把它加在某个类上:@MyAnnotation public class AnnotationTest{}
       用反射进行测试AnnotationTest的定义上是否有@MyAnnotation
      根据反射测试的问题,引出@Retention元注解,其三种取值:RetetionPolicy.SOURCE、RetetionPolicy.CLASS、RetetionPolicy.RUNTIME;分别对应:
java源文件-->class文件-->内存中的字节码。
       思考:@Override、@SuppressWarnings和@Deprecated这三个注解的属性值分别是什么?(SOURCE、SOURCE、RUNTIME)
       @Target元注解
       Target的默认值为任何元素。
      设置Target等于ElementType.METHOD,原来加在类上的注解就报错了,改为用数组方式设置{ElementType.METHOD,ElementType.TYPE}就可以了。
      元注解以及其枚举属性值不用记,只要会看jdk提供那几个基本注解的API帮助文档的定义或其源代码,按图索骥即可查到,或者直接看java.lang.annotation包下面的类。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/ *使用元注解对自定义注解进行标注
 * RetentionPolicy是一个枚举类,有三个 枚举值常量SOURCE CLASS RUNTIME
 * * /
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE}) //表示任意类型的元素,不一定是注解在方法上
public @interface MyAnnotation {
}
import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Annotation;
@MyAnnotation
public class AnnotationTest {
    public static void main(String[] args) {
       if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){
           MyAnnotation myAnn = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
           System.out.println(myAnn);
       } 
    }
}
 
Class类实现了该接口,并且如Enum、interface、@interface等,虽然不属于Class类,但都是java中的一种类型,因此都实现了接口Type。该接口的概念更宽泛。
 
       @MyAnnotation(color="red")
       用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法
       MyAnnotation aØ       = (MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
       System.out.println(a.color());
    可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象
       为属性指定缺省值:
      String color() default "yellow";
       value属性:
       String value() default "zxx";
 
      数组类型的属性
      int [] arrayAttr() default {1,2,3};
       @MyAnnotation(arrayAttr={2,3,4})
      如果数组属性中只有一个元素,这时候属性值部分可以省略大括号
       枚举类型的属性
       EnumTest.TrafficLamp lamp() ;
       @MyAnnotation(lamp=EnumTest.TrafficLamp.GREEN)
       注解类型的属性:
       MetaAnnotation annotationAttr() default @MetaAnnotation("xxxx");
      @MyAnnotation(annotationAttr=@MetaAnnotation(“yyy”) )
       可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用代码如下:
       MetaAnnotation ma =  myAnnotation.annotationAttr();
       System.out.println(ma.value());

      注解的详细语法可以通过看java语言规范了解,即看java的language specification。


---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值