黑马程序员07_基础加强01
来源:互联网 发布:淘宝卖家退款要验证码 编辑:程序博客网 时间:2024/05/21 20:28
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
可变参数、自动装箱拆箱、字符串池、枚举、Class、反射
1、可变参数:适用于参数个数不确定,类型确定的情况。
注意:可变参数出现在参数列表的最后, ... 位于变量类型和变量名之间,前后有无空格都可以。
可以把可变参数看成是一个数组来使用
package com.itheima.xiaozhi; public class VariableParameter { //可以把可变参数看成是一个数组 public static void main(String[] args) { System.out.println(add(1,2,3,4)); System.out.println(add(1, new int[] {2,3,4})); } public static int add(int a, int...args) {//int[] args for (int i = 0; i < args.length; i++) { a+=args[i]; } return a; } }
将一个数组赋给一个可变参数,通常采用的原则是[拆]
比如将new String[ ]{ "1", "2", "3"} 赋给String ... strs,是先将String数组拆成三个字符串“1”,“2”,“3”,然后对应赋给可变参数
但是如果将一个int类型的数组赋给可变参数类型Object ... os,采用的原则也是拆吗?
看下面代码
package com.xiaozhi.hellotest; public class Test { public static void main(String[] args) { int[] a=new int[]{1,2,3}; System.out.println( a instanceof Object); } }
这两行代码说明int[ ]属于Object的实例,一个简单类型的数组属于一个Object实例,那么将一个简单类型数组赋给Object ... os 可变参数,其实就想当于传了一个Object对象参数而已。所以采用的原则不是拆了。
下面代码页可以证明这一点
package com.itheima.xiaozhi; import java.util.Arrays; import java.util.List; public class VariableParam { public static void main(String[] args) { // public static <T> List<T> asList(T... a)(Object[]os) List list = Arrays.asList("1", "2", "3"); System.out.println(list);// [1, 2, 3] String arr[] = { "1", "2", "3", "4" }; list = Arrays.asList(arr); System.out.println(list);// [1, 2, 3, 4] Integer nums2[] = { 1, 2, 3, 4, 5 }; list = Arrays.asList(nums2); System.out.println(list);// [1, 2, 3, 4, 5] int nums[] = { 1, 2, 3, 4, 5 }; list = Arrays.asList(nums); System.out.println(list.size());//1 System.out.println(list);// [[I@120d62b] } }
2、基本数据类型的自动装箱和拆箱:基本数据类型和它所对应的包装类可以自动转换
比如Integer i = 1;1自动装箱成为Integer类型
int j = i+1; i自动拆箱成int类型与1相加
享元设计模式:
integer i1 =3;
integer i2 =3;
i1 == i2 结果是true
integer i3 =137;
integer i4 =137;
i3 == i4 结果是false
对于小的整数(-128 ~ 127),装箱成为的对象都是同一个对象,这就是享元模式的一个小例子
package com.xiaozhi.box; public class Test { public static void main(String[] args) { //自动装箱 Integer integer1=13; Integer integer2=13; //自动拆箱 System.out.println(integer1+2); //享元设计模式:对于小的整数,装箱装成的对象都是同一个 System.out.println(integer1==integer2); Integer integer3=137; Integer integer4=137; System.out.println(integer3==integer4); } }
3、字符串池
String s="abc";//放入字符串池,如果池中已经有该字符串,直接使用
String s=new String("abc");//直接新建对象不放入字符串池
枚举类里面的每一个元素都是一个类的实例对象。
枚举类里面的元素必须位于类的里面的所有成分之前。
枚举类的构造方法必须是private私有的。
JDK1.5以后一个枚举类这样写
enum Grade{ A,B,C,D; }
JDK1.5以前没有枚举类,是这样子做的,构造方法是私有的(只有类内可以创建本类对象)每个对象都是public(公有的,外面可以访问) static (可以通过类名访问)final(不允许改变的)
class Grade{ private Grade(){} public static final Grade A=new Grade(); public static final Grade B=new Grade(); public static final Grade C=new Grade(); public static final Grade D=new Grade(); }
也就是说当枚举只有一个元素时,可以作为单列的一种实现方式。
enum Grade{A}带有抽象方法的枚举类,要在创建枚举类的同时实现抽象方法
下面是示例代码,代码中还有values()方法、valueOf(String str)、ordinal()的使用
package com.xiaozhi.enumration; public class Test { public static void main(String[] args) { for(Grade a:Grade.values()) System.out.println(a.getScore()); System.out.println(Grade.valueOf("A").getScore());//优 System.out.println(Grade.A.ordinal());//0 } } enum Grade{ A("90-100"){ public String getScore(){ return "优"; } }, B("80-90"){ public String getScore(){ return "良"; } }, C("70-80"){ public String getScore(){ return "中"; } }, D("60-70"){ public String getScore(){ return "差"; } }; private String value; private Grade(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public abstract String getScore(); }
5、Class:
内存中的每一份字节码就是一个Class类的实例对象
类是用来描述一类事物的共性,比如人这个类的对象有张三李四王五,而Class的对象有Math.class Data.class
如果要加载的类字节码已经被加载过,那么第二次加载就返回已经加载在内存中的字节码。
java中有9个预定义的Class实例对象,基本数据类型boolean byte char short int long float double 和关键字void
isPrimitive()可以判断是否是基本数据类型的字节码
package com.xiaozhi.box; public class Test { public static void main(String[] args) { System.out.println(int.class == Integer.class); System.out.println(int.class.isPrimitive());//是否是基本数据类型的字节码 System.out.println(int.class == Integer.TYPE);//表示基本数据类型int的class实例 } }
6、反射:就是把java类中的各个成分映射成相应的java类
例如,一个java类中用一个Class类的对象来表示,一个类的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
要反射的类
package com.xiaozhi.reflect; import java.io.InputStream; import java.util.List; public class Person { private String name; private int password; public Person() { System.out.println("无参构造函数"); } public Person(String name) { this.name = name; System.out.println("一个参数的构造函数"+name); } public Person(String name, int password) { this.name = name; this.password = password; System.out.println("两个参数的构造函数"+name+":"+password); } private Person(List list){ System.out.println("私有构造函数"); } public void aa1(){ System.out.println("aa1"); } public void aa1(String name,int password){ System.out.println("name= "+name+" password="+password); } public Class[] aa1(String name,int[] password){ return new Class[]{String.class}; } private void aa1(InputStream in){ System.out.println(in); } public static void aa1(int num){ System.out.println(num); } public static void main(String []args){ System.out.println("main"); } }加载类的字节码的三种方法
第一种:Class.forName(String str)
第二种:类名.class
第三种:new 类名 .getClass()
反射构造函数调用Class的getConstructor(构造函数的参数的Class对象)
package com.xiaozhi.reflect; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) throws Exception { //加载类的字节码的三种方法 // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Class clazz=new Person().getClass(); // Class clazz=Person.class; //无参的构造函数 // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Constructor constructor=clazz.getConstructor(null); // Person person=(Person) constructor.newInstance(null); //一个参数的构造函数 // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Constructor constructor=clazz.getConstructor(String.class); // Person person=(Person) constructor.newInstance("jingtianxiaozhi"); //两个参数的构造函数 // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Constructor constructor=clazz.getConstructor(String.class,int.class); // Person person=(Person) constructor.newInstance("jingtianxiaozhi",100); //私有的构造函数 // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Constructor constructor=clazz.getDeclaredConstructor(List.class); // constructor.setAccessible(true); // Person person=(Person) constructor.newInstance(new ArrayList()); //默认的 Class clazz=Class.forName("com.xiaozhi.reflect.Person"); Person p=(Person) clazz.newInstance(); } }反射方法
getMethod(方法名 ,方法参数)
获取main方法比较特殊,有两种方法:
第一种:把字符串数组包装在一个Object数组中
第二种:把字符串数组强制转换成Object类型,骗过编译器
package com.xiaozhi.reflect; import java.io.FileInputStream; import java.io.InputStream; import java.lang.reflect.Method; public class Test2 { public static void main(String[] args) throws Exception { //无参的方法 //public void aa1() // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Method method=clazz.getMethod("aa1",null); // Person person=new Person(); // method.invoke(person,null); //有参数的方法 //public void aa1(String name,int password) // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Method method=clazz.getMethod("aa1",String.class,int.class); // Person person=new Person(); // method.invoke(person,"jingtianxiaozhi",22); //有返回值的方法 //public Class[] aa1(String name,int[] password) // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Method method=clazz.getMethod("aa1",String.class,int[].class); // Person person=new Person(); // Class cs[]=(Class[]) method.invoke(person,"jingtianxiaozhi",new int[]{1,2,3}); // System.out.println(cs[0]); //private void aa1(InputStream in){ // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Method method=clazz.getDeclaredMethod("aa1",InputStream.class); // method.setAccessible(true); // Person person=new Person(); // method.invoke(person,new FileInputStream("c:\\jingtianxiaozhi.txt")); //静态方法 //public static void aa1(int num){ // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Method method=clazz.getMethod("aa1",int.class); // method.invoke(null,22); //main方法 Class clazz=Class.forName("com.xiaozhi.reflect.Person"); Method method=clazz.getMethod("main", String[].class); method.invoke(null,new String[]{"13"});//Object...//拆开之后,main方法接受的参数是字符串 method.invoke(null,new Object[]{new String[]{"13"}});//Object...//拆开之后,是一个字符串数组 method.invoke(null,(Object)new String[]{"13"}); } }反射字段:
getField(字段名)
package com.xiaozhi.reflect; import java.lang.reflect.Field; public class Test { public static void main(String[] args) throws Exception { //获取公有字段类型字段值 // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Field field=clazz.getField("name"); // Class type=field.getType(); // System.out.println(type); // Person person=new Person(); // String value=(String)field.get(person); // System.out.println(value); //设置公有字段值 // field.set(person,"xiaozhi"); // System.out.println(field.get(person)); //获取私有字段类型以及值 // Class clazz=Class.forName("com.xiaozhi.reflect.Person"); // Field field=clazz.getDeclaredField("password"); // field.setAccessible(true); // Class type=field.getType(); // System.out.println(type); // Person person=new Person(); // Integer value=(Integer)field.get(person); // System.out.println(value); //获取静态字段类型以及值 Class clazz=Class.forName("com.xiaozhi.reflect.Person"); Field field=clazz.getField("age"); Class type=field.getType(); System.out.println(type); Integer value=(Integer)field.get(null); System.out.println(value); } } class Person{ public String name="aaa"; private int password=123; public static int age=22; }
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
- 黑马程序员07_基础加强01
- 黑马程序员_基础加强01
- 黑马程序员_基础加强01
- 黑马程序员_基础加强
- 黑马程序员_基础加强
- 黑马程序员_基础加强_枚举
- 黑马程序员_基础加强_反射
- 黑马程序员_基础加强_注解
- 黑马程序员_基础加强_代理
- 黑马程序员_基础加强_枚举
- 黑马程序员_基础加强_注解
- 黑马程序员_基础加强_反射
- 黑马程序员_基础加强_注解
- 黑马程序员_日记04(java基础加强01)
- 黑马程序员_java基础加强_代理
- 黑马程序员_基础加强path1
- 黑马程序员_基础加强path2
- 黑马程序员_基础加强path3
- 好的习惯与可持续发展
- HDU 3342
- 更新 第五章 绘图基础(设备环境)
- android中的语音识别
- Poi导出excel设置单元格数值格式
- 黑马程序员07_基础加强01
- 阿里巴巴面试题目集合
- 我的java学习日记(3)
- NDK与java传递中文字符的解决办法
- JDK动态代理--Demo
- linux内核锁机制-不可睡眠锁之RCU
- 4.0 编译apk中无classes.dex问题解决方法
- sql之left join、right join、inner join的区别
- json对象创建