Внутренний класс и вложенный статический класс в Java - это классы, объявленные внутри другого класса, известного как класс верхнего уровня в Java. В терминологии Java. Если вы объявляете вложенный класс static, он будет вызывать вложенный статический класс в Java, а нестатический вложенный класс просто называется Inner Class.
Что такое Inner Class в Java?
Любой класс, который не является верхним уровнем или объявлен внутри другого класса, известен как вложенный класс и из тех вложенных классов, класс, которые объявлены нестатические известны как класс Inner в Java. в Java есть три типа класса Inner:
1) Локальный внутренний класс - объявляется внутри кодового блока или метода. 2) Анонимный внутренний класс - это класс, который не имеет имени для ссылки и инициализируется в том же месте, где он создается. 3) Внутренний класс члена - объявлен как нестационарный член внешнего класса.
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
@Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
Что такое вложенный статический класс в Java?
Вложенный статический класс - это другой класс, который объявлен внутри класса как члена и статично. Вложенный статический класс также объявляется членом внешнего класса и может быть закрытым, открытым или защищенным, как и любой другой член. Одним из основных преимуществ вложенного статического класса над внутренним классом является то, что экземпляр вложенного статического класса не привязан к какому-либо закрывающему экземпляру класса Outer. Вам также не нужен какой-либо экземпляр класса Outer для создания экземпляра вложенного статического класса в Java .
1) Он может получить доступ к статическим членам данных внешнего класса, включая частные. 2) Статический вложенный класс не может получить доступ к нестатистическому (экземпляру) элементу данных или method .
public class NestedStaticExample {
public static void main(String args[]){
StaticNested nested = new StaticNested();
nested.name();
}
//static nested class in java
private static class StaticNested{
public void name(){
System.out.println("static nested class example in java");
}
}
}
Ссылка: Внутренний класс и вложенный Static Class в Java с примером
Власть, которую Вы можете иметь по сборщику "мусора" и как это управляет объектным набором, очень мощна, специально для продолжительных и чувствительных ко времени приложений. Это запускается со слабых, мягких, и фантомных ссылок в java.lang.ref пакете. Смотрите на тех, специально для создания кэшей (существует java.util. WeakHashMap уже). Теперь выройте немного глубже в ReferenceQueue, и Вы начнете иметь еще больше контроля. Наконец захватите документы о самом сборщике "мусора", и Вы будете в состоянии управлять, как часто он работает, размеры различных областей набора и типы используемых алгоритмов (для Java 5 см. http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html ).
JVisualVM от каталога bin в распределении JDK. При контроле и даже профилировании любого JAVA-приложения, даже один Вы не запускались ни с какими специальными параметрами. Только в последних версиях Java 6SE JDK.
Можно получить доступ к заключительным локальным переменным и параметрам в блоках инициализации и методах локальных классов. Рассмотрите это:
final String foo = "42";
new Thread() {
public void run() {
dowhatever(foo);
}
}.start();
Немного как закрытие, не так ли?
Аннотация, Обрабатывающая API от Java 6, смотрит очень перспектива для генерации кода и статической проверки кода.
Что-то, что действительно удивило меня, было пользовательским механизмом сериализации.
, В то время как эти методы частные!! , они" загадочно " названы JVM во время сериализации объекта.
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
Этот способ, которым можно создать собственную сериализацию для создания его больше "безотносительно" (безопасный, быстрый, редкий, легкий и т.д.)
, Это - что-то, что действительно должно рассматривать, должна ли большая информация быть передана через узлы. Механизм сериализации может быть изменен для отправки половины данных. Существуют много раз, когда узкие места не находятся в платформе, а в сумме той отправленной канавки провод, может сохранить Вас тысячи dlls в аппаратных средствах.
Вот статья. http://java.sun.com/developer/technicalArticles/Programming/serialization/
Как насчет файлов Свойств в Вашем выборе кодировки? Используемый, чтобы быть при загрузке Свойств Вы обеспечили InputStream и load()
, метод декодировал его как ISO-8859-1. Вы могли на самом деле хранить файл в некотором другом кодировании, но необходимо было использовать отвратительный взлом как это после загрузки для надлежащего декодирования данных:
String realProp = new String(prop.getBytes("ISO-8859-1"), "UTF-8");
, Но, с JDK 1.6, существует load()
метод, который берет Читателя вместо InputStream, что означает, что можно использовать корректное кодирование с начала (существует также store()
метод, который берет Писателя). Это походит на довольно грандиозное предприятие мне, но это, кажется, было, крался в JDK без шумихи вообще. Я только наткнулся на него несколько недель назад, и быстрый поиск Google, поднятый всего одно передающее упоминание о нем.
"константа" является ключевым словом, но Вы не можете использовать ее.
int const = 1; // "not a statement"
const int i = 1; // "illegal start of expression"
я предполагаю, что разработчики компилятора думали, что это могло бы использоваться в будущем, и они должны сохранить зарезервированным.
Можно создать строковый sprintf-стиль с помощью String.format ().
String w = "world";
String s = String.format("Hello %s %d", w, 3);
можно, конечно, также использовать специальные спецификаторы для изменения вывода.
Больше здесь: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax
Joshua Bloch, новый Эффективный Java, является хорошим ресурсом.
Некоторые приемы потока управления, finally
вокруг return
оператор:
int getCount() {
try { return 1; }
finally { System.out.println("Bye!"); }
}
правила для определенное присвоение проверит, что последняя переменная всегда присваивается посредством простого анализа потока управления:
final int foo;
if(...)
foo = 1;
else
throw new Exception();
foo+1;
Функторы довольно прохладны. Они достаточно близки к указателю функции, который все обычно быстры для высказывания, невозможно в Java.
SwingWorker для того, чтобы легко справиться с обратными вызовами пользовательского интерфейса от фоновых потоков.
Перекрестные типы позволяют, Вы к (своего рода вид) делаете перечисления, которые имеют иерархию наследования. Вы не можете наследовать реализацию, но можно делегировать ее к классу помощника.
enum Foo1 implements Bar {}
enum Foo2 implements Bar {}
class HelperClass {
static <T extends Enum<T> & Bar> void fooBar(T the enum) {}
}
Это полезно, когда у Вас есть много различных перечислений, которые реализуют своего рода шаблон. Например, много пар перечислений, которые имеют отношения отцов и детей.
enum PrimaryColor {Red, Green, Blue;}
enum PastelColor {Pink, HotPink, Rockmelon, SkyBlue, BabyBlue;}
enum TransportMedium {Land, Sea, Air;}
enum Vehicle {Car, Truck, BigBoat, LittleBoat, JetFighter, HotAirBaloon;}
можно ли записать общие методы, которые говорят "Хорошо, учитывая перечисление значений, это - родитель некоторых других перечислимых значений, какой процент всех возможных дочерних перечислений дочернего типа имеют это конкретное родительское значение как их родителя?", и имейте все это безопасное с точки зрения типов и обошедшееся без кастинг. (например: то "Море" составляет 33% всех возможных механизмов и "Зеленые" 20% всех возможных Пастелей).
код похожи на это. Это довольно противно, но существуют способы сделать его лучше. Обратите внимание в particuar, что сами "листовые" классы довольно аккуратны - универсальные классы имеют объявления, которые ужасно ужасны, но Вы только пишете им onece. После того как универсальные классы там, затем используют их, легко.
import java.util.EnumSet;
import javax.swing.JComponent;
public class zz extends JComponent {
public static void main(String[] args) {
System.out.println(PrimaryColor.Green + " " + ParentUtil.pctOf(PrimaryColor.Green) + "%");
System.out.println(TransportMedium.Air + " " + ParentUtil.pctOf(TransportMedium.Air) + "%");
}
}
class ParentUtil {
private ParentUtil(){}
static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
float pctOf(P parent) {
return (float) parent.getChildren().size() / //
(float) EnumSet.allOf(parent.getChildClass()).size() //
* 100f;
}
public static <P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> //
EnumSet<C> loadChildrenOf(P p) {
EnumSet<C> cc = EnumSet.noneOf(p.getChildClass());
for(C c: EnumSet.allOf(p.getChildClass())) {
if(c.getParent() == p) {
cc.add(c);
}
}
return cc;
}
}
interface Parent<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
Class<C> getChildClass();
EnumSet<C> getChildren();
}
interface Child<P extends Enum<P> & Parent<P, C>, C extends Enum<C> & Child<P, C>> {
Class<P> getParentClass();
P getParent();
}
enum PrimaryColor implements Parent<PrimaryColor, PastelColor> {
Red, Green, Blue;
private EnumSet<PastelColor> children;
public Class<PastelColor> getChildClass() {
return PastelColor.class;
}
public EnumSet<PastelColor> getChildren() {
if(children == null) children=ParentUtil.loadChildrenOf(this);
return children;
}
}
enum PastelColor implements Child<PrimaryColor, PastelColor> {
Pink(PrimaryColor.Red), HotPink(PrimaryColor.Red), //
Rockmelon(PrimaryColor.Green), //
SkyBlue(PrimaryColor.Blue), BabyBlue(PrimaryColor.Blue);
final PrimaryColor parent;
private PastelColor(PrimaryColor parent) {
this.parent = parent;
}
public Class<PrimaryColor> getParentClass() {
return PrimaryColor.class;
}
public PrimaryColor getParent() {
return parent;
}
}
enum TransportMedium implements Parent<TransportMedium, Vehicle> {
Land, Sea, Air;
private EnumSet<Vehicle> children;
public Class<Vehicle> getChildClass() {
return Vehicle.class;
}
public EnumSet<Vehicle> getChildren() {
if(children == null) children=ParentUtil.loadChildrenOf(this);
return children;
}
}
enum Vehicle implements Child<TransportMedium, Vehicle> {
Car(TransportMedium.Land), Truck(TransportMedium.Land), //
BigBoat(TransportMedium.Sea), LittleBoat(TransportMedium.Sea), //
JetFighter(TransportMedium.Air), HotAirBaloon(TransportMedium.Air);
private final TransportMedium parent;
private Vehicle(TransportMedium parent) {
this.parent = parent;
}
public Class<TransportMedium> getParentClass() {
return TransportMedium.class;
}
public TransportMedium getParent() {
return parent;
}
}
Плагин Java следующего поколения, найденный в Обновлении Java 1.6 10 и позже, имеет некоторые очень аккуратные функции:
Много других вещей, которые документируются здесь: http://jdk6.dev.java.net/plugin2/
[еще 1110] от этого выпуска здесь: http://jdk6.dev.java.net/6u10ea.html
Строка Параметризованная Фабрика классов.
Class.forName( className ).newInstance();
Загрузка ресурс (файл свойств, xml, xslt, отображают и т.д.) из файла .
this.getClass().getClassLoader().getResourceAsStream( ... ) ;
банки развертывания Экземпляры того же класса могут получить доступ к членам парламента, не занимающим официального поста других экземпляров:
class Thing {
private int x;
public int addThings(Thing t2) {
return this.x + t2.x; // Can access t2's private value!
}
}
Прочитайте «Пазлы Явы» Джошуа Блоха, и вы будете как просветлены, так и в ужасе.
URL-адреса исходного кода. Например, вот некоторый законный исходный код Java:
http://google.com
(Да, это было в Java Puzzlers. Я засмеялся ...)
Люди иногда немного удивляются, когда понимают, что это возможно вызвать частные методы и получить доступ / изменить частные поля с помощью отражения ...
Рассмотрим следующий класс:
public class Foo {
private int bar;
public Foo() {
setBar(17);
}
private void setBar(int bar) {
this.bar=bar;
}
public int getBar() {
return bar;
}
public String toString() {
return "Foo[bar="+bar+"]";
}
}
Выполнение этой программы ...
import java.lang.reflect.*;
public class AccessibleExample {
public static void main(String[] args)
throws NoSuchMethodException,IllegalAccessException, InvocationTargetException, NoSuchFieldException {
Foo foo=new Foo();
System.out.println(foo);
Method method=Foo.class.getDeclaredMethod("setBar", int.class);
method.setAccessible(true);
method.invoke(foo, 42);
System.out.println(foo);
Field field=Foo.class.getDeclaredField("bar");
field.setAccessible(true);
field.set(foo, 23);
System.out.println(foo);
}
}
... даст следующий результат:
Foo[bar=17]
Foo[bar=42]
Foo[bar=23]
Уловка оптимизации, которая упрощает поддержку кода и снижает уязвимость к ошибкам параллелизма.
public class Slow {
/** Loop counter; initialized to 0. */
private long i;
public static void main( String args[] ) {
Slow slow = new Slow();
slow.run();
}
private void run() {
while( i++ < 10000000000L )
;
}
}
$ time java Slow
реальный 0 мин. 15,397 с
$ time java Slow
реальный 0m20.012s
$ time java Slow
реальный 0 мин. 18,645 с
Среднее значение: 18,018 с
public class Fast {
/** Loop counter; initialized to 0. */
private long i;
public static void main( String args[] ) {
Fast fast = new Fast();
fast.run();
}
private void run() {
long i = getI();
while( i++ < 10000000000L )
;
setI( i );
}
private long setI( long i ) {
this.i = i;
}
private long getI() {
return this.i;
}
}
$ time java Быстро
реальный 0 мин. 12,003 с
$ time java Fast
реальный 0 мин. 9,840 с
$ time java Fast
real 0m9.686s
Среднее значение: 10.509s
Для ссылки на переменную области класса требуется больше байт-кодов, чем на переменную области действия метода. Добавление вызова метода перед критическим циклом добавляет небольшие накладные расходы (и вызов может быть встроен компилятором в любом случае).
Еще одно преимущество этого метода (всегда использующего аксессоры) состоит в том, что он устраняет потенциальную ошибку в Медленный класс. Если бы второй поток постоянно сбрасывал значение i на 0 (например, путем вызова slow.setI (0)
), класс Slow мог никогда не заканчивать цикл. Вызов метода доступа и использование локальной переменной исключает эту возможность.
Протестировано с использованием J2SE 1.6.0_13 в Linux 2.6.27-14.
Уже упоминалось , что конечный массив может использоваться для передачи переменной из анонимных внутренних классов.
Другой, возможно лучший и менее уродливый подход - использовать AtomicReference ( или AtomicBoolean / AtomicInteger /…) из пакета java.util.concurrent.atomic.
Одним из преимуществ этого является то, что эти классы также предоставляют такие методы, как compareAndSet
, которые могут быть полезны, если вы создаете несколько потоков, которые могут изменять одну и ту же переменную.
Еще один полезный связанный шаблон:
final AtomicBoolean dataMsgReceived = new AtomicBoolean(false);
final AtomicReference<Message> message = new AtomicReference<Message>();
withMessageHandler(new MessageHandler() {
public void handleMessage(Message msg) {
if (msg.isData()) {
synchronized (dataMsgReceived) {
message.set(msg);
dataMsgReceived.set(true);
dataMsgReceived.notifyAll();
}
}
}
}, new Interruptible() {
public void run() throws InterruptedException {
synchronized (dataMsgReceived) {
while (!dataMsgReceived.get()) {
dataMsgReceived.wait();
}
}
}
});
В этом конкретном примере мы могли бы просто подождать, пока сообщение не станет ненулевым, однако null часто может быть допустимым значением, и тогда вам нужно использовать отдельный флаг для завершения ожидания.
waitMessageHandler (… )
выше - еще один полезный шаблон: он где-то устанавливает обработчик, затем начинает выполнение Interruptible , которое может вызвать исключение, а затем удаляет обработчик в блоке finally, например:
private final AtomicReference<MessageHandler> messageHandler = new AtomicReference<MessageHandler>();
public void withMessageHandler(MessageHandler handler, Interruptible logic) throws InterruptedException {
synchronized (messageHandler) {
try {
messageHandler.set(handler);
logic.run();
} finally {
messageHandler.set(null);
}
}
}
] Здесь я предполагаю, что метод messageHandler (если он не равен нулю) handleMessage (…)
вызывается другим потоком при получении сообщения. messageHandler не должен быть просто типа MessageHandler : таким образом вы будете синхронизировать изменяющуюся переменную, что явно является ошибкой.
Конечно, это не так.
Большинство людей не знают, что могут клонировать массив.
int[] arr = {1, 2, 3};
int[] arr2 = arr.clone();
Запятая и массив. Это допустимый синтаксис: String s [] = {
«123»,
«234» ,
};
Use StringBuilder
instead of StringBuffer
when you don't need synchronized management included in StringBuilder
. It will increase the performance of your application.
Improvements for Java 7 would be even better than any hidden Java features:
Don't use those infinite <> syntax at instanciation:
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
// Can now be replaced with this:
Map<String, List<String>> anagrams = new HashMap<>();
Use String in switch, instead of old-C int:
String s = "something";
switch(s) {
case "quux":
processQuux(s);
// fall-through
case "foo":
case "bar":
processFooOrBar(s);
break;
case "baz":
processBaz(s);
// fall-through
default:
processDefault(s);
break;
}
This old code:
static void copy(String src, String dest) throws IOException {
InputStream in = new FileInputStream(src);
try {
OutputStream out = new FileOutputStream(dest);
try {
byte[] buf = new byte[8 * 1024];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
} finally {
out.close();
}
} finally {
in.close();
}
}
can now be replaced by this much simpler code:
static void copy(String src, String dest) throws IOException {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest)) {
byte[] buf = new byte[8192];
int n;
while ((n = in.read(buf)) >= 0)
out.write(buf, 0, n);
}
}
На самом деле, что мне нравится в Java, так это то, как мало там скрытых уловок. Это очень очевидный язык. Настолько, что через 15 лет почти все, о которых я могу думать, уже перечислены на этих нескольких страницах.
Возможно, большинство людей знает, что Collections.synchronizedList () добавляет синхронизацию в список. Чего вы не можете знать, если не прочитаете документацию, так это того, что вы можете безопасно выполнять итерацию по элементам этого списка, синхронизируя сам объект списка.
CopyOnWriteArrayList может быть неизвестен некоторым,
Идентификаторы могут содержать иностранные языковые символы, такие как умлауты:
вместо написания:
String title="";
Кто-то мог написать:
String Überschrift="";
Не читал об этом
Integer a = 1;
Integer b = 1;
Integer c = new Integer(1);
Integer d = new Integer(1);
Integer e = 128;
Integer f = 128;
assertTrue (a == b); // again: this is true!
assertFalse(e == f); // again: this is false!
assertFalse(c == d); // again: this is false!
Подробнее об этом, поисшив Java Pool of Integer (внутренний кэш-кеш »от -128 до 127 для AutoBoxing) или посмотреть в Integer.Valueof
Java 6 (от Sun) поставляется с встроенным переводчиком Javascrip.
http://java.sun.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html#sjsengine
Я могу добавить объект Scanner. Он лучше всего подходит для парсинга.
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();