Upload
murat-yener
View
145
Download
0
Embed Size (px)
Citation preview
OpenJDK for a’N’droidlingsMurat Yener
@yenerm
who am I?Java, Web, Android
Android @Intel
Speaker (Devoxx, JavaOne, DroidCon..)
GDG Organizer
Book Author (Java EE DP, Android Studio)
GDE on Android & Java Champion
what the JDK?
Android is Java
but.. not on JRE
based on Apache Harmony
Object.java Object.class classes.dx
Java7? Java8?
but Harmony is Java 6??
Java 7 introduces changes to JVM! (JSR-292)
Java 8 introduces language features based on…
Java 8 Language FeaturesDefault and Static Interface methods
Lambda Expressions
Repeatable Annotations
Method References
Type Annotations
https://developer.android.com/guide/platform/j8-jack.html
Default Methodspublic interface TimeClient { void setTime(int hour, int minute, int second); void setDate(int day, int month, int year); void setDateAndTime(int day, int month, int year, int hour, int minute, int second); LocalDateTime getLocalDateTime(); static ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { return ZoneId.systemDefault(); } } default ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } }
Default Methodspublic interface TimeClient { void setTime(int hour, int minute, int second); void setDate(int day, int month, int year); void setDateAndTime(int day, int month, int year, int hour, int minute, int second); LocalDateTime getLocalDateTime(); static ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { return ZoneId.systemDefault(); } } default ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } }
Default Methodspublic interface TimeClient { void setTime(int hour, int minute, int second); void setDate(int day, int month, int year); void setDateAndTime(int day, int month, int year, int hour, int minute, int second); LocalDateTime getLocalDateTime(); static ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { return ZoneId.systemDefault(); } } default ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } } https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
Lambdas
JButton testButton = new JButton("Test Button"); testButton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e){ System.out.println("Click Detected by Anon Class"); } });
Lambdas
JButton testButton = new JButton("Test Button"); testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listner"));
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-QuickStart/index.html
Lambdas with Streamsroster .stream() .filter( p -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25) .map(p -> p.getEmailAddress()) .forEach(email -> System.out.println(email));
Lambdas with Stream
Q: print emails of male persons between 18-25 years old from
a source of objects…
Lambdas with Streampublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
public int getAge() {} public void printPerson() {} }
Q: print emails of male persons between 18-25 years old from
a source of objects…
Lambdas with Streamsroster .stream() .filter( p -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25) .map(p -> p.getEmailAddress()) .forEach(email -> System.out.println(email));
Lambdas with Streamsroster .stream() .filter( p -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25) .map(p -> p.getEmailAddress()) .forEach(email -> System.out.println(email));
Lambdas with Streamsroster .stream() .filter( p -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25) .map(p -> p.getEmailAddress()) .forEach(email -> System.out.println(email));
Lambdas with Streamsroster .stream() .filter( p -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25) .map(p -> p.getEmailAddress()) .forEach(email -> System.out.println(email));
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
Method References
Lambdas are great for anon methods…
but what if the method already exists..
Method Referencespublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
}
Method Referencespublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
}
Array.sort(personArray, ???)
Method Referencespublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
}
class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); } }
Method Referencespublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
}
class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); } }
Arrays.sort(rosterAsArray, new PersonAgeComparator());
Method Referencespublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
}
class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); } }
Arrays.sort(rosterAsArray, (Person a, Person b) -> { return a.getBirthday().compareTo(b.getBirthday()); } );
Method Referencespublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
public static int compareByAge(Person a, Person b) { return a.birthday.compareTo(b.birthday); } }
Method Referencespublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
public static int compareByAge(Person a, Person b) { return a.birthday.compareTo(b.birthday); } }
Arrays.sort(rosterAsArray, compareByAge);
Method Referencespublic class Person { public enum Sex { MALE, FEMALE } String name; LocalDate birthday; Sex gender; String emailAddress;
public static int compareByAge(Person a, Person b) { return a.birthday.compareTo(b.birthday); } }
Arrays.sort(rosterAsArray, Person::compareByAge);
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Repeatable Annotations
public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; }
@Schedule(dayOfMonth=“last”, dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... }
Repeatable Annotations@Repeatable(Schedules.class) public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; }
@Schedule(dayOfMonth=“last”) @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... }
public @interface Schedules { Schedule[] value(); }
https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
Type Annotations
Pre Java 8, annotations could only be applied to declarations
With Java 8, annotations can also be applied to any type use
@NonNull String str;
https://docs.oracle.com/javase/tutorial/java/annotations/type_annotations.html
how is this possible?!?
JSR-292
introduced with Java 7
new instruction on JVM! invokedynamic
new Java API (java.lang.invoke)
new classes (MethodType, MethodHandle…)
Invoking methods - reflectionObject str, Object from, Object to; Method m = str.getClass().getMethod(“replace”, from.getClass, to.getClass));
m.invoke(str, from, to);
Invoking methods - invokeExactObject str, Object from, Object to; Method m = str.getClass().getMethod(“replace”, from.getClass, to.getClass));
MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandle mh = lookup.unreflect(method); mh.asType(mt.generic());
mh.invokeExact(str, from, to);
Invoking methods - invokeGenericObject str, Object from, Object to; Method m = str.getClass().getMethod(“replace”, from.getClass, to.getClass));
MethodHandles.Lookup lookup = MethodHandles.lookup(); MethodHandle mh = lookup.unreflect(method); mh.asType(mt.generic());
mh.invokeGeneric(str, from, to);
https://www.youtube.com/watch?v=STDBY5kT4_M
Invoke Dynamic
provides linking at runtime
directly translates to VM
used in lambdas*
Jack & Jill
enable Java 8 with Jack
Jack shrinks, obfuscates, repackages, multidex
Jill translates jar files to Jack
Jack
javac: java to class dx: class to dex
Jack: java to jack to dex
Jack can handle Lambdas… goodbye RetroLambda
Proguard included!
Enable Jack!android { ... defaultConfig { ... jackOptions { enabled true } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
</slides> <questions>
thanks!! @yenerm