Строка ошибки «Ссылка на объект, не установленная на экземпляр объекта.» указывает, что вы не назначили экземпляр объекта объектной ссылке, и все же вы получаете доступ к свойствам / методам этого объекта.
например: скажем, у вас есть класс под названием myClass и он содержит одно свойство prop1.
public Class myClass
{
public int prop1 {get;set;}
}
Теперь вы получаете доступ к этому prop1 в каком-то другом классе, как показано ниже:
public class Demo
{
public void testMethod()
{
myClass ref = null;
ref.prop1 = 1; //This line throws error
}
}
выше строки выдает ошибку, потому что ссылка класса myClass объявлена, но не создана, или экземпляр объекта не назначается referecne этого класса.
Чтобы исправить это, вам нужно создать экземпляр (присвоить объект ссылке на этот класс).
public class Demo
{
public void testMethod()
{
myClass ref = null;
ref = new myClass();
ref.prop1 = 1;
}
}
Мне не нравится идея использования Reflection для этого. SecurityManager
.
FutureTask
является хорошим вариантом в качестве других опций из пакета java.util.concurrent. Это не просто опасно для его отсутствия в некоторых рефакторингах. Мой любимый для простых задач:
Executors.newSingleThreadExecutor().submit(task);
немного короче, чем создание Thread (задача - Callable или Runnable)
Это действительно не связано, но если я должен асинхронно вызывать метод, например. matches (), я бы использовал:
private final static ExecutorService service = Executors.newFixedThreadPool(10);
public static Future<Boolean> matches(final String x, final String y) {
return service.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
return x.matches(y);
}
});
}
Тогда для вызова асинхронного метода я бы использовал:
String x = "somethingelse";
try {
System.out.println("Matches: "+matches(x, "something").get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
Я тестировал это, и он работает. Просто подумал, что это может помочь другим, если они просто пришли для «асинхронного метода».
Это, вероятно, не настоящее решение, но теперь - в Java 8 - вы можете сделать этот код, по крайней мере, немного лучше, используя лямбда-выражение.
final String x = "somethingelse";
new Thread(() -> {
x.matches("something");
}
).start();
И вы могли бы даже сделать это в одном line, все еще имея его довольно читаемым.
new Thread(() -> x.matches("something")).start();
Java 8 представил CompletableFuture, доступный в пакете java.util.concurrent.CompletableFuture, можно использовать для вызова асинхронного вызова:
CompletableFuture.runAsync(() -> {
// method call or code to be asynch.
});
CompletableFuture
упоминался в другом ответе, но тот использовал целую цепочку supplyAsync(...)
. Это простая оболочка, которая идеально подходит для вопроса.
– ndm13
5 February 2018 в 16:20
Возможно, вы захотите также рассмотреть класс java.util.concurrent.FutureTask
.
Если вы используете Java 5 или более позднюю версию, FutureTask - это реализация «подстановочного асинхронного вычисления» под ключ. "
Есть еще более богатые асинхронные действия по планированию выполнения, доступные в пакете java.util.concurrent
(например, ScheduledExecutorService
), но FutureTask
могут иметь все необходимые вам функции.
Я даже зашел так далеко, чтобы сказать, что уже не рекомендуется использовать первый образец кода, который вы дали в качестве примера с тех пор, как FutureTask
стал доступен. (Предполагая, что вы находитесь на Java 5 или новее.)
Я только что обнаружил, что есть более чистый способ сделать ваш
new Thread(new Runnable() {
public void run() {
//Do whatever
}
}).start();
(по крайней мере, в Java 8), вы можете использовать лямбда-выражение, чтобы сократить его до:
new Thread(() -> {
//Do whatever
}).start();
Так же просто, как сделать функцию в JS!
Вы можете использовать синтаксис Java8 для CompletableFuture, таким образом вы можете выполнять дополнительные вычисления async на основе результата вызова функции async.
например:
CompletableFuture.supplyAsync(this::findSomeData)
.thenApply(this:: intReturningMethod)
.thenAccept(this::notify);
Для этого вы можете использовать Future-AsyncResult.
@Async
public Future<Page> findPage(String page) throws InterruptedException {
System.out.println("Looking up " + page);
Page results = restTemplate.getForObject("http://graph.facebook.com/" + page, Page.class);
Thread.sleep(1000L);
return new AsyncResult<Page>(results);
}
Вы можете использовать AsyncFunc
из Cactoos :
boolean matches = new AsyncFunc(
x -> x.matches("something")
).apply("The text").get();
Он будет выполнен в фоновом режиме, и результат будет доступен в get()
как Future
.
ExecutorService
, поэтому вы можете позвонитьshutdown()
, когда вам нужно. – Daniel Szalay 12 June 2012 в 10:36