黑马程序员 Java 加强

守給你的承諾、 提交于 2020-04-07 07:43:14

---------------------- android培训java培训、期待与您交流! ---------------------- 

1.可变参数

可变参数特点:

  • 只能出现在参数列表的最后;
  • ...位于变量类型和变量名之间,前面有无空格都可以;
  • 调用可变参数的方法时,编译器为该可变参数隐式创建一个数组,在方法体内以数组的形式访问可变参数
 7 public class VariableParameter {
 8 
 9     public static int add(int x,int...args)
10     {
11         int sum=x;
12         for (int i = 0; i < args.length; i++) {
13             
14             sum=sum+args[i];    
15         }
16         return sum;
17     }
18     public static void main(String args[])
19     {
20         System.out.println(add(2,4));
21         System.out.println(add(1,2,3,4,5,6));
22     }
23 }

 2.枚举

 

1.用enum定义枚举类默认继承了java.lang.Enum类而不是继承了Object类。其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口

2.枚举类的构造函数只能使用private访问修饰符,如果省略了其构造器的访问控制符,则默认使用private修饰;

3.枚举类的所有实例必须在枚举类中显式列出,否则这个枚举类将永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰,无需程序员显式添加。

枚举示例

 1 public class EnumTest {
 2     public static void main(String args[])
 3     {
 4         WeekDay weekday1 =WeekDay.FRI;
 5         System.out.println(weekday1);
 6         System.out.println(weekday1.name());
 7         System.out.println(weekday1.ordinal());
 8         System.out.println(WeekDay.valueOf("SUN").toString());
 9         System.out.println(WeekDay.values().length);
10     }
11     public enum WeekDay
12     {
13         SUN(1),MON,TUE,WED,THI,FRI,SAT;
14         private WeekDay()
15         {
16             System.out.println("first");
17         }
18         private WeekDay(int x)
19         {
20             System.out.println("second");
21         }
22     }

在枚举中还可以定义抽象方法 

交通灯枚举示例

 1     public enum TrafficLamp
 2     {
 3         RED(60)
 4         {
 5             public TrafficLamp nextLamp()
 6             {
 7                 return GREEN;
 8             }
 9         },GREEN(45)
10         {
11             public TrafficLamp nextLamp()
12             {
13                 return YELLOW;
14             }
15         },YELLOW(15)
16         {
17             public TrafficLamp nextLamp()
18             {
19                 return RED;
20             }
21         
22         };
23         public abstract TrafficLamp nextLamp();
24         private int time;
25         private TrafficLamp(int time){this.time=time;
26     }
27     }
28 }

 

枚举的遍历

public class EnumTest {
    public static void main(String[] args){
        for(Week w:Week.values()){
            System.out.println(w);
        }
    }
}

枚举的常用方法

int compareTo方法

String name()返回枚举实例的名称

int ordinal() 返回枚举值在枚举中的索引

String toString()返回枚举的实例名称 比name更常用

public static valueOf()

public class EnumTest {
    public static void main(String[] args){
        Week day =Week.FRI;
        System.out.println(day);//FRI
        System.out.println(day.name());//FRI
        System.out.println(day.ordinal());//4
        System.out.println(Week.valueOf("SUN").toLocaleString());//星期日
        System.out.println(Week.values().length);//7  获取枚举长度
    }
}

枚举的构造函数

public enum Gender {
    MALE("男"),FEMALE("女");
    private String name;
    private Gender(String name){
        this.name =name;
    }
    public String getName(){
        return this.name;
    }
    public String toString(){
        String name = null;
        switch(this){
        case MALE:
            name="男";
            break;
        case FEMALE:
            name="女";
            break;
        }
        return name;
    }
    
}

3.反射

如何得到各个字节码对应的实例对象?
 * 1.类名.class  System.class
 * 2.对象.getClass() 
 * 3.Class.forName("类名");
九个预定义Class实例对象
 * int.class == Integer.TYPE
 * 
 * 数组类型Class实例对象
 * Class.isArray()
 * 数组类型Class实例对象
 * Class.isArray()
 
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException{
        String str1="abc";
        Class cls1=str1.getClass();
        Class cls2=String.class;
        Class cls3=Class.forName("java.lang.String");
        System.out.println(cls1==cls2);//true
        System.out.println(cls2==cls3);//true
        System.out.println(int.class.isPrimitive());//true
        System.out.println(int.class == Integer.class);//false
        System.out.println(int.class ==Integer.TYPE);//true
        System.out.println(int[].class.isArray());//true
    }

}

* 得到类中的构造函数
* getConstructors(构造函数参数)

public class ReflectDemo3 {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        //获得构造函数
        Constructor constructor=Class.forName("java.lang.String").getDeclaredConstructor(StringBuffer.class);
        //利用构造函数创建实例对象
        String str =(String) constructor.newInstance(new StringBuffer("abc"));
        System.out.println(str);
    }

}

字段反射

import java.lang.reflect.Field;

public class ReflectDemo4 {
    public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
        Student s =new Student(12,"zhangsan");
        Field age =s.getClass().getDeclaredField("age");
        age.setAccessible(true);
        System.out.println(age.getInt(s));
        Field name =s.getClass().getDeclaredField("name");
        name.setAccessible(true);//暴力破解
        System.out.println(name.get(s));
        //设置值
        Field[] fields=s.getClass().getFields();
        for(Field field :fields){
            if(field.getType()==String.class){
            String oldValue =(String) field.get(s);
            String newValue=oldValue.replace('b' ,'a');
            field.set(s, newValue);
            }        
        }
        System.out.println(s);
        
    }

}

反射获取方法

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
 * 获取方法:getMethod(函数名的字符串,变量的字节码
 * 使用方法静态方法invoke(使用方法的对象,变量)
 */

public class ReflectDemo5 {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        Method method =Class.forName("java.lang.String").getMethod("charAt", int.class);
        //使用方法
        String str ="abcd";
        System.out.println(method.invoke(str, 1));
        
    }

4.JavaBean

JavaBean:特殊的Java类,主要用于传递数据信息,这种Java类的方法用于访问私有的字段,方法名称具有特定规则。

PropertyDescriptor属性描述符:获取属性名称及对象,再调用getReadMethod或getWriteMethod方法返回一个Method对象,再调用invoke()即可

复杂操作:采用遍历BeanInfo的所有方式来查找和设置某个ReflectPoint的x属性。在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo,得到的BeanInfo对象封装了这个类当作JavaBean看的结果信息

使用BeanUtils工具包操作JavaBean

用ecplice加入jar包,分别导入BeanUtils和loading包,并设置BuildPath。

用BeanUtils代替上面的内省操作。

get属性返回的结果为字符串,set可设置任意类型的的对象,通常使用字符串。

PropertyUtils:get属性返回的结果为该属性本来的类型,set属性只接受该属性本来的类型。

5.注解

注解:等于为程序打上了某种标记,可以加在类,包,字段,方法,方法的参数及局部变量上。

@Deprecated :标记此程序元素已过时

@SuppressWarnings :取消显示指定的编译器警告。

@Override :表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。  

 

注解的定义和反射调用

定义一个最简单的注解:public @interface MyAnnotation {}

把它加在某个类上:@MyAnnotation public class AnnotationTest{}

用反射进行测试AnnotationTest的定义上是否有@MyAnnotation

@Retention元注解三种取值:RetetionPolicy.SOURCE、RetetionPolicy.CLASS、RetetionPolicy.RUNTIME;分别对应:java源文件-->class文件-->内存中的字节码。

@Target元注解

Target的默认值为任何元素,设置Target等于ElementType.METHOD,则只能作用于方法

多种位置用数组方式设置{ElementType.METHOD,ElementType.TYPE}

 

注解添加属性

定义基本类型的属性
在注解类中增加String color();
引用:@MyAnnotation(color=“red”)

用反射获得注解对应的实例对象后,再通过对象调用属性对应的方法。
MyAnnotation a=(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation)
System.out.println(a.color);

为属性定义缺省值String color() default “red”;

Value属性 String value();
如果一个注解只有一个名称为value的属性,且你只想设置value的属性,可以省略,@MyAnnotation(“red”);

6.类加载器

Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader

类加载器也是Java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是不是java类,这正是BootStrap。

Java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其指定一个父级类装载器对象或者默认采用系统类装载器为其父级类加载。  

自定义的类加载器的必须继承ClassLoader

覆盖loadClass  findClass方法 defineClass方法

 

编写class文件进行加密的工具:

操作步骤:

编写一个对文件内容进行简单加密的程序。

编写了一个自己的类装载器,可实现对加密过的类进行装载和解密。

编写一个程序调用类加载器加载类,在源程序中不能用该类名定义引用变量,因为编译器无法识别这个类。程序中可以除了使用ClassLoader.load方法之外,还可以使用设置线程的上下文类加载器或者系统类加载器,然后再使用Class.forName。

 

 

---------------------- android培训java培训、期待与您交流! ---------------------- 详细请查看:http://edu.csdn.net/heima

 

---------------------- android培训java培训、期待与您交流! ---------------------- 详细请查看:http://edu.csdn.net/heima

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!