Stringbuilder、StringJoiner、String.join()举例
public static void main(String[] args) { System.out.println("first master"); //Stringbuild String[] name = new String[]{"Bob","Alice","tom"}; StringBuilder sb = new StringBuilder(); sb.append("hello,"); for(String str:name){ sb.append(str).append(","); } sb.delete(sb.length()-1,sb.length()); sb.append("!"); System.out.println(sb); //Stringjioner,参数分别是 分隔符 前缀 后缀 StringJoiner sj = new StringJoiner(";","Hello,","!"); for(String str:name){ sj.add(str); } System.out.println(sj); //string.join(),参数分别是 分隔符 string数组 String s = String.join(",",name); System.out.println(s); }
javabean
- 若干
private
实例字段; - 通过
public
方法来读写实例字段。
public class Student{ private string name; private int age; public string getName() { return name; } public int getAge() { return age; } public void setName(string name) { this.name = name; } public void setAge(int age) { this.age = age; } }
random()
Random ra = new Random(); for (int i =0;i<10;i++){ // 100 以内的整数 System.out.println(ra.nextInt(100)); } // [0.0,1.0) System.out.println(Math.random());
log
默认级别是INFO,因此,INFO级别以下的日志,不会被打印出来。
级别:
- SEVERE
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINEST
Logger logger = Logger.getGlobal(); logger.info("start process..."); logger.warning("memory is running out..."); logger.fine("ignored."); logger.severe("process will be terminated...");
反射(需要再看看)
通过Class 实例获取 class信息的方法叫做反射
获取class实例的方法:
一、直接通过一个class
的静态变量class
获取
Class cls = String.class;
二、知道实例变量,可以通过getClass()方法获取
String s = "hello"; Class cls = s.getClass(); System.out.println(cls);
三、如果知道一个class
的完整类名,可以通过静态方法Class.forName()
获取
Class cls = Class.forName("java.lang.String");
Class实例在JVM中是唯一的,以下代码可以证明
动态加载:JVM在执行Java程序的时候,并不是一次性把所有用到的class全部加载到内存,而是第一次需要用到class时才加载。
访问字段
public class Testmain { public static void main(String[] args) throws Exception { //System.out.println("first master"); Person1 p = new Person1("Xiao Ming"); System.out.println(p.getName()); // "Xiao Ming" //反射获取 Class类 Class c = p.getClass(); //获取 Person1的私有变量 name,如果是public变量 直接 get()即可 Field f = c.getDeclaredField("name"); //设置 私有变量 可改,如果是要修改public变量,不需要加此行代码 f.setAccessible(true); //改 私有变量 f.set(p,"Xiao Hong"); System.out.println(p.getName()); // "Xiao Hong" } } class Person1 { private String name; public Person1(String name) { this.name = name; } public String getName() { return this.name; } }
注解
自定义注解
一、用@interface
定义注解:
public @interface Report {
}
二、添加参数、默认值:
public @interface Report { int type() default 0; String level() default "info"; //把最常用的参数定义为value(),推荐所有参数都尽量设置默认值 default String value() default ""; }
三、用元注解配置注解:
//必须设置@Target和@Retention,@Retention一般设置为RUNTIME,因为我们自定义的注解通常要求在运行期读取。一般情况下,不必写@Inherited和@Repeatable。 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Report { int type() default 0; String level() default "info"; String value() default ""; }
泛型
泛型就是编写模板代码来适应任意类型,如 ArrayList<T> 就是一种泛型,T可以是 String 、Integer等
泛型是“擦拭法”实现的:虚拟机对泛型其实一无所知,所有的工作都是编译器做的。举例:
//编译器上的代码 Pair<String> p = new Pair<>("Hello", "world"); String first = p.getFirst(); String last = p.getLast(); //虚拟机上的代码 Pair p = new Pair("Hello", "world"); String first = (String) p.getFirst(); String last = (String) p.getLast();
泛型的局限:
1、<T>
不能是基本类型,例如int
,因为实际类型是Object
,Object
类型无法持有基本类型
2、无法取得带泛型的Class
泛型可以继承,例如:父类的类型是Pair<Integer>
,子类的类型是IntPair
,可以这么继承:
public class IntPair extends Pair<Integer> { }